ImageView in ListView that expands maximum width

2019-06-24 12:04发布

i have a ListView whose items are ImageViews, for the sake of discussion. i want the image to scale to the width of the ListView's rows, and maintain it's aspect ratio. here's a simplified version of the ListView's item layout,

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:padding="4dp" >

        <FrameLayout
            android:id="@+id/page_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="visible" >

            <ImageView
                android:id="@+id/image"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:scaleType="fitCenter"
                android:src="@drawable/some_image" />
        </FrameLayout>
    </FrameLayout>

</LinearLayout>

the ImageView's width is match_parent, and all ancestors of it are the same. layout designer shows that the ImageView's dimensions span the entire width, but the image inside does not.

EDIT: the image is scaling correctly. the problem is that the height of the list view row is such that the width can't scale to the right size. if i use fitXY, it does scale the width, but then the aspect ratio is incorrect.

any ideas? thanks.

2条回答
甜甜的少女心
2楼-- · 2019-06-24 12:21

answering my own question ...

i couldn't find any way to accomplish this without creating a custom view. in a nutshell, the custom view sets it's own dimensions to the real (not scaled) dimensions of the drawable behind it.

public class ResizableImageView extends ImageView {

    public static interface OnSizeChangedListener {

        void onSizeChanged(int width, int height);
    }

    private OnSizeChangedListener onSizeChangedListener = null;

    public ResizableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = width * getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth();
        setMeasuredDimension(width, height);
        if (onSizeChangedListener != null) {
            onSizeChangedListener.onSizeChanged(width, height);
        }
    }

    public void setOnSizeChangedListener(OnSizeChangedListener listener) {
        this.onSizeChangedListener = listener;
    }
}

in my case i needed to obtain the resized value in order to size the other views, hence the listener interface.

查看更多
Lonely孤独者°
3楼-- · 2019-06-24 12:31

If what you want is to maintain the aspect ratio, according to the Android API Guide, I think that you have to change android:scaleType="fitCenter" for android:scaleType="centerInside" or maybe android:scaleType="centerCrop" as fitCenter doesn't maintain the aspect ratio of the image.

查看更多
登录 后发表回答