我试图扩展位于ImageView
内的RelativeLayout
。我希望宽度填充父级,同时仍保持图像的宽高比。这听起来非常像我可以在XML布局文件中使用centerCrop。不同之处在于我不希望图像居中对齐。我想要的是将图像对齐到父图像的顶部,并且要裁剪的图像底部有任何多余的图像。
这是XML:
<RelativeLayout
android:background="#f00"
android:id="@+id/skyline_header"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="25">
<ImageView
android:id="@+id/bg_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg_img"/>
</RelativeLayout>
这是我的代码:
final RelativeLayout headerContainer = (RelativeLayout) view.findViewById(R.id.skyline_header);
final ImageView iv = (ImageView) view.findViewById(R.id.bg_image);
ViewTreeObserver vto = headerContainer.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
headerContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
double imgAspectRatio = (double)iv.getMeasuredWidth() / (double)iv.getMeasuredHeight();
int screenWidth = getActivity().getResources().getDisplayMetrics().widthPixels;
Log.d("tag", Integer.toString(iv.getMeasuredWidth()));
Log.d("tag", Integer.toString(iv.getMeasuredHeight()));
Log.d("tag", Double.toString(imgAspectRatio));
Log.d("tag", Integer.toString(screenWidth));
int newHeight = (int) ((double)screenWidth * imgAspectRatio);
img.setLayoutParams(new RelativeLayout.Layout(screenWidth, newHeight));
img.requestLayout();
}
});
如果您只设置scaleType="fitCenter"
,此代码会生成您所看到的内容。它填充容器的高度,使图像居中,并在左侧和右侧留下边距。
输出很奇怪。它显示图像视图的宽度与屏幕相同:
1440
562
2.5622775800711746
1440
希望这会概念性地传达我现在所拥有的东西:
我希望图片能够伸展以填充整个水平空间(没有可见的红色剩余),而不会使游泳者看起来非常奇特(即保持纵横比完好无损)。游泳者下面的水可以根据需要进行裁剪,以保持前两个要求。
答案 0 :(得分:3)
好吧,幸运的是,android API提供了另一个scaleType
:matrix
,因此您可以自由地显示所需的部分图像,将这些代码行添加到onCreate
Activity
方法中 final ImageView iv = (ImageView) findViewById(R.id.iv);
iv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int viewWidth = iv.getMeasuredWidth();
int viewHeight = iv.getMeasuredHeight();
Drawable src = iv.getDrawable();
if (src != null) {
int srcWidth = src.getIntrinsicWidth();
int srcHeight = src.getIntrinsicHeight();
float wRatio = (float) viewWidth / srcWidth;
float hRatio = (float) viewHeight / srcHeight;
float scaleFactor = Math.max(wRatio, hRatio);
float hTranslate = (viewWidth - scaleFactor * srcWidth) / 2;
Matrix matrix = new Matrix();
matrix.setScale(scaleFactor, scaleFactor);
matrix.postTranslate(hTranslate, 0);
iv.setScaleType(ImageView.ScaleType.MATRIX);
iv.setImageMatrix(matrix);
Log.i("test", "srcWidth: " + srcWidth);
Log.i("test", "srcHeight: " + srcHeight);
Log.i("test", "viewWidth: " + viewWidth);
Log.i("test", "viewHeight: " + viewHeight);
Log.i("test", "wRatio: " + wRatio);
Log.i("test", "hRatio: " + hRatio);
Log.i("test", "scaleFactor: " + scaleFactor);
Log.i("test", "hTranslate: " + hTranslate);
}
iv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
1}}:
OnGlobalLayoutListener
首先注册一个wRatio
,这样您就可以在合适的时间访问视图的维度(我相信您已经知道了),然后计算hRatio
(宽度比率)和{{1 }}(高度比率)使用提供的参数并选择较大的参数作为scaleFactor
(因此您确保drawable
覆盖了整个视图),还需要对齐drawable
中心水平(hTranslate
扮演的角色),最后创建矩阵,我们就在那里!
原始图片:
centerCrop结果:
topCrop结果(我们通过代码执行的操作)