Android Stretch ImageView填充宽度,保持纵横比,对齐顶部

时间:2016-07-08 20:00:04

标签: android image android-layout

我试图扩展位于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

希望这会概念性地传达我现在所拥有的东西:

enter image description here

我希望图片能够伸展以填充整个水平空间(没有可见的红色剩余),而不会使游泳者看起来非常奇特(即保持纵横比完好无损)。游泳者下面的水可以根据需要进行裁剪,以保持前两个要求。

1 个答案:

答案 0 :(得分:3)

好吧,幸运的是,android API提供了另一个scaleTypematrix,因此您可以自由地显示所需的部分图像,将这些代码行添加到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扮演的角色),最后创建矩阵,我们就在那里!

原始图片:

enter image description here

centerCrop结果:

enter image description here

topCrop结果(我们通过代码执行的操作)

enter image description here