我正在尝试展开一个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
希望这将在概念上传达我现在所拥有的:
我希望图片能延伸到整个水平空间(没有可见的红色残影),而又不会使游泳者看起来异常地宽(即保持长宽比不变)。可以根据需要修剪游泳者下方的水,以保持前两个要求。
好吧,幸运的是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);
}
});
首先注册一个,OnGlobalLayoutListener
这样您将在正确的时间访问视图的尺寸(我相信您已经知道了),然后使用提供的参数计算wRatio
(宽度比)和hRatio
(高度比),然后选择较大的作为scaleFactor
(因此您确保drawable
覆盖整个视图),还需要drawable
水平居中对齐(这是角色hTranslate
扮演),最后创建矩阵,我们就在这里!
原始图片:
centerCrop结果:
topCrop结果(我们通过代码执行的操作)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句