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>