如何将ImageView的ScaleType设置为TopCrop

22

我正在编写 Android 代码,有一个 ImageView。我想将其 scaletype 设置为 topcrop。虽然我在选项中找到了 centercrop,但这不是我的要求。我该怎么做?

4个回答

32

自定义 Android ImageView,用于对所包含的 drawable 进行顶部裁剪缩放。

import android.content.Context;
import android.graphics.Matrix;
import android.widget.ImageView;

/**
* ImageView to display top-crop scale of an image view.
*
* @author Chris Arriola
*/
public class TopCropImageView extends ImageView {

public TopCropImageView(Context context) {
    super(context);
    setScaleType(ScaleType.MATRIX);
}

@Override
protected boolean setFrame(int l, int t, int r, int b) {
    final Matrix matrix = getImageMatrix();

    float scale;
    final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
    final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
    final int drawableWidth = getDrawable().getIntrinsicWidth();
    final int drawableHeight = getDrawable().getIntrinsicHeight();

    if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
        scale = (float) viewHeight / (float) drawableHeight;
    } else {
        scale = (float) viewWidth / (float) drawableWidth;
    }

    matrix.setScale(scale, scale);
    setImageMatrix(matrix);

    return super.setFrame(l, t, r, b);
}        
}

https://gist.github.com/arriolac/3843346


如何实现这个。我在stackoverflow上问了一个关于此的问题http://stackoverflow.com/questions/32359213/trying-to-use-custom-imageview-topcrop-in-android-but-the-the-app-stops。 - Santhosh
@Jay,它运行得很好。我正在onLayout()方法中进行矩阵计算,该方法在旋转时也会被调用,其中setFrame不会被调用。 - box
2
我在开头调用 super.setFrame(l, t, r, b);,否则 getWidth() 将返回 0。 - JackWu

14

我只是希望有一个不需要太多额外工作的临时解决方案。试试这个。

<ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:scrollY="-100dp"
    android:id="@+id/poster"
   />

scrollY可以上下拉动您的图像。试试不同的dp,您会找到正确的尺寸。


8
虽然这可以完成手头的任务,但无法适用于不同的屏幕分辨率或父视图尺寸。可能不建议在生产环境中使用,因为你将在实际应用中获得意外结果。 :) - DoctorD
是的,我也是吃了亏才学会的。在不同的屏幕上它的表现是不同的。 - rahulxyz
我只需要稍微移动一下图片,这个方法完美地解决了问题,谢谢。 - HB.

4

1

修正版本:

  • 立即调用setFrame
  • 不重复使用Matrix -> 这会导致问题,当图片重新加载太快(使用Picasso),图片会被缩放过多
import android.content.Context
import android.graphics.Matrix
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView

class TopCropImageView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : AppCompatImageView(context, attrs, defStyleAttr) {

    init {
        scaleType = ScaleType.MATRIX
    }

    override fun setFrame(l: Int, t: Int, r: Int, b: Int): Boolean {
        super.setFrame(l, t, r, b)
        val matrix = Matrix()
        val scale: Float
        val viewWidth: Int = width - paddingLeft - paddingRight
        val viewHeight: Int = height - paddingTop - paddingBottom
        val drawableWidth: Int = drawable.intrinsicWidth
        val drawableHeight: Int = drawable.intrinsicHeight
        scale = if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
            viewHeight.toFloat() / drawableHeight.toFloat()
        } else {
            viewWidth.toFloat() / drawableWidth.toFloat()
        }
        matrix.setScale(scale, scale)
        imageMatrix = matrix
        return true
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接