79660262

Date: 2025-06-10 10:33:50
Score: 0.5
Natty:
Report link

It's fun that here comes a new answer after 14 years.

After searching around for more than a couple of hours, by referring to the comment at top of this topic:
https://stackoverflow.com/a/55255113/853191

I worked out a solution as below:


import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;

import androidx.appcompat.widget.AppCompatImageView;

public class ScaleMatrixImageView extends AppCompatImageView {

    public ScaleMatrixImageView(Context context) {
        super(context);
        init();
    }

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

    public ScaleMatrixImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        setScaleType(ScaleType.MATRIX); // very important
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        updateMatrix();
    }

    private void updateMatrix() {
        Drawable drawable = getDrawable();
        if (drawable == null) return;

        int dWidth = drawable.getIntrinsicWidth();
        int dHeight = drawable.getIntrinsicHeight();
        int vWidth = getWidth();
        int vHeight = getHeight();

        if (dWidth == 0 || dHeight == 0 || vWidth == 0 || vHeight == 0) return;

        // Compute scale to fit width, preserve aspect ratio
        float scale = (float) vWidth / (float) dWidth;
        float scaledHeight = dHeight * scale;

        Matrix matrix = new Matrix();
        matrix.setScale(scale, scale);

        if (scaledHeight > vHeight) {
            // The image is taller than the view -> need to crop bottom
            float translateY = 0; // crop bottom, don't move top
            matrix.postTranslate(0, translateY);
        } else {
            // The image fits inside the view vertically — center it vertically
            float translateY = (vHeight - scaledHeight) / 2f;
            matrix.postTranslate(0, translateY);
        }

        setImageMatrix(matrix);
    }


}

Use it in layout:

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
        <com.renren.android.chimesite.widget.ScaleMatrixImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/watermark"
            />
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_messages"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </FrameLayout>

and it looks like: enter image description here

Reasons:
  • Blacklisted phrase (1): stackoverflow
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
Posted by: LiuWenbin_NO.