gpt4 book ai didi

android - ImageView 的 setImageMatrix 在某些设备上无法正常工作(可能比 Android 4.4 更早)

转载 作者:搜寻专家 更新时间:2023-11-01 08:45:33 29 4
gpt4 key购买 nike

我试图通过以下代码在触摸事件上移动 ImageView:

public class ScrollableImageView extends ImageView {
private GestureDetectorCompat gestureDetectorCompat;

public ScrollableImageView(Context context) {
this(context, null);
}

public ScrollableImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public ScrollableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setScaleType(ScaleType.MATRIX);

gestureDetectorCompat = new GestureDetectorCompat(context,
new MySimpleOnGestureListener(this));
}

@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
gestureDetectorCompat.onTouchEvent(event);
return true;
}

public void scroll(float distance) {
Matrix imageMatrix = getImageMatrix();
imageMatrix.postTranslate(distance, 0);
setImageMatrix(imageMatrix);
invalidate();
}

private static class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener {
private ScrollableImageView scrollableImageView;

public MySimpleOnGestureListener(ScrollableImageView scrollableImageView) {
this.scrollableImageView = scrollableImageView;
}

@Override
public boolean onDown(MotionEvent e) {
Utils.log("onDown");
return true;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
scrollableImageView.scroll(-distanceX);
return true;
}
}
}

起初,一切都在 Nexus 5(Android 4.4.4 和 Lollipop)上运行良好。但后来我尝试了 Android 的旧版本,如 4.0.4(Galaxy S2) 或 Nexus S(4.1.1)...但都没有用。

经过一段时间的努力,我想到了这个解决方案,并且它在所有设备上都运行良好:

(注意现在,我通过本地对象跟踪 ImageView 的矩阵对象,而不是通过 ImageView 的 getImageMatrix() 获取它)

public class ScrollableImageView extends ImageView {
private GestureDetectorCompat gestureDetectorCompat;
private Matrix imageMatrix;

public ScrollableImageView(Context context) {
this(context, null);
}

public ScrollableImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public ScrollableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setScaleType(ScaleType.MATRIX);

imageMatrix = new Matrix();

gestureDetectorCompat = new GestureDetectorCompat(context,
new MySimpleOnGestureListener(this));
}

@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
gestureDetectorCompat.onTouchEvent(event);
return true;
}

public void scroll(float distance) {
imageMatrix.postTranslate(distance, 0);
setImageMatrix(imageMatrix);
invalidate();
}

private static class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener {
private ScrollableImageView scrollableImageView;

public MySimpleOnGestureListener(ScrollableImageView scrollableImageView) {
this.scrollableImageView = scrollableImageView;
}

@Override
public boolean onDown(MotionEvent e) {
Utils.log("onDown");
return true;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
scrollableImageView.scroll(-distanceX);
return true;
}
}
}

我找到了解决方案,但我仍然不明白为什么我以前的代码不起作用?!

我试图进行研究,但唯一有意义的是 ImageView 的 getImageMatrix() 的文档:

Return the view's optional matrix. This is applied to the view's drawable when it is drawn. If there is no matrix, this method will return an identity matrix. Do not change this matrix in place but make a copy. If you want a different matrix applied to the drawable, be sure to call setImageMatrix().

然后它让我更困惑的是 不要就地更改这个矩阵,而是制作一个副本,这样做有什么意义?为什么我不能像在以前的代码中那样做? (获取 ImageView 的当前矩阵,然后应用翻译,然后按照文档所述通过 setImageMatrix() 将其设置回来)

有人请给我一些启发,这对我来说太困惑了。

最佳答案

好的,伙计们,我明白了!

实际上文档是有道理的。

Return the view's optional matrix. This is applied to the view's drawable when it is drawn. If there is no matrix, this method will return an identity matrix. Do not change this matrix in place but make a copy. If you want a different matrix applied to the drawable, be sure to call setImageMatrix().

由于 ics_mr1 的 ImageView 源代码中的这段代码:

public void setImageMatrix(Matrix matrix) {
// collaps null and identity to just null
if (matrix != null && matrix.isIdentity()) {
matrix = null;
}

// don't invalidate unless we're actually changing our matrix
if (matrix == null && !mMatrix.isIdentity() ||
matrix != null && !mMatrix.equals(matrix)) {
mMatrix.set(matrix);
configureBounds();
invalidate();
}
}

所以如果我喜欢:

   Matrix imageMatrix = getImageMatrix();
imageMatrix.postTranslate(distance, 0);
setImageMatrix(imageMatrix);

matrix != null && !mMatrix.equals(matrix) 将为 false 因为我重复使用了相同的 Matrix 对象(这就是为什么文档说 Do not就地更改此矩阵但制作副本),则不会发生任何事情,因为不满足任何条件。

然后现在我想出了一个非常优雅的解决方案:

   Matrix imageMatrix = new Matrix(getImageMatrix());
imageMatrix.postTranslate(distance, 0);
setImageMatrix(imageMatrix);

就是这样
哎呀

关于android - ImageView 的 setImageMatrix 在某些设备上无法正常工作(可能比 Android 4.4 更早),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28720166/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com