Qxnedy 2023-10-10 15:57 采纳率: 0%
浏览 6

我自己写了个简单的查看图片界面,用的Picasso库和第三方组件PhotoView,实现图片的查看手指拖动,双指缩放图片效果,但是第一次触摸图片的时候图片会自动放大到占满屏幕

我自己写了个简单的查看图片界面,用的Picasso库和第三方组件PhotoView,实现图片的查看手指拖动,双指缩放图片效果,但是第一次触摸图片的时候图片会自动放大到占满屏幕,然后移动到左上角,请问一个佬们这个什么原因造成的。

这是第一次进入未操作时的图片

img

这是手指首次触摸屏幕时的图片(首次触摸屏幕就会变成这样,之后的单指。双指操作都是没问题的)

img

以下是我的代码:


import android.graphics.Matrix;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import com.github.chrisbanes.photoview.PhotoView;
import com.hust.ipad.R;
import com.squareup.picasso.Picasso;

/**
 * 查看图片界面
 */
public class ImageActivity extends BaseActivity {
    private PhotoView imageView;
    private Matrix mMatrix;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image);

        initView();
    }

    /**
     * 初始化组件
     */
    private void initView() {
        imageView = findViewById(R.id.image_view);
        String imagePath = getIntent().getStringExtra("imagePath");
        Picasso.get()
                .load("file://" + imagePath)
                .into(imageView);

        mMatrix = new Matrix();
        imageView.setOnTouchListener(new View.OnTouchListener() {
            float lastX, lastY;
            int mode = 0;
            float oldDist;
            float midX, midY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN: // 手势按下
                        if (event.getPointerCount() == 1) {
                            lastX = event.getX();
                            lastY = event.getY();
                        }
                        mode = 1; // 单指模式
                        mMatrix.postScale(1.0f, 1.0f);
                        mMatrix.postTranslate(0, 0);
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN: // 多点触控按下
                        oldDist = distance(event);
                        if (oldDist > 10f) {
                            midPoint(event);
                            mode = 2; // 双指模式
                        }
                        break;
                    case MotionEvent.ACTION_MOVE: // 手势移动
                        if (mode == 1) { // 单指模式
                            float dx = event.getX() - lastX;
                            float dy = event.getY() - lastY;
                            lastX = event.getX();
                            lastY = event.getY();
                            // 计算ImageView应该移动的距离
                            mMatrix.postTranslate(dx, dy);
                        } else if (mode == 2) { // 双指模式
                            float newDist = distance(event);
                            if (newDist > 10f) {
                                float scale = newDist / oldDist;
                                oldDist = newDist;
                                // 计算ImageView应该缩放的比例
                                mMatrix.postScale(scale, scale, midX, midY);
                            }
                        }
                        break;
                    case MotionEvent.ACTION_UP: // 手势松开
                    case MotionEvent.ACTION_POINTER_UP: // 多点触控松开
                        mode = 0;
                        break;
                }
                imageView.setImageMatrix(mMatrix);
                return true;
            }

            // 计算双指之间的距离
            private float distance(MotionEvent event) {
                float x = event.getX(0) - event.getX(1);
                float y = event.getY(0) - event.getY(1);
                return (float) Math.sqrt(x * x + y * y);
            }

            // 计算双指之间的中心点坐标
            private void midPoint(MotionEvent event) {
                float x0 = event.getX(0);
                float y0 = event.getY(0);
                float x1 = event.getX(1);
                float y1 = event.getY(1);
                midX = (x0 + x1) / 2;
                midY = (y0 + y1) / 2;
            }
        });
    }
}

以下时布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    android:gravity="center"
    android:orientation="vertical">
    
    <com.github.chrisbanes.photoview.PhotoView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerInside"/>
</LinearLayout>

  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2023-10-11 19:41
    关注

    引自强大而免费的微信小程序:皆我百晓生。


    问题可能是你在onTouch方法中的ACTION_DOWN事件中设置了mMatrix的缩放比例为1,导致了第一次触摸图片时图片会自动放大到占满屏幕。你可以尝试将mMatrix.postScale(1.0f, 1.0f)这行代码从ACTION_DOWN事件中移除。

    修改后的代码如下:

    imageView.setOnTouchListener(new View.OnTouchListener() {
        float lastX, lastY;
        int mode = 0;
        float oldDist;
        float midX, midY;
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN: // 手势按下
                    if (event.getPointerCount() == 1) {
                        lastX = event.getX();
                        lastY = event.getY();
                    }
                    mode = 1; // 单指模式
                    break;
                case MotionEvent.ACTION_POINTER_DOWN: // 多点触控按下
                    oldDist = distance(event);
                    if (oldDist > 10f) {
                        midPoint(event);
                        mode = 2; // 双指模式
                    }
                    break;
                case MotionEvent.ACTION_MOVE: // 手势移动
                    if (mode == 1) { // 单指模式
                        float dx = event.getX() - lastX;
                        float dy = event.getY() - lastY;
                        lastX = event.getX();
                        lastY = event.getY();
                        // 计算ImageView应该移动的距离
                        mMatrix.postTranslate(dx, dy);
                    } else if (mode == 2) { // 双指模式
                        float newDist = distance(event);
                        if (newDist > 10f) {
                            float scale = newDist / oldDist;
                            oldDist = newDist;
                            // 计算ImageView应该缩放的比例
                            mMatrix.postScale(scale, scale, midX, midY);
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP: // 手势松开
                case MotionEvent.ACTION_POINTER_UP: // 多点触控松开
                    mode = 0;
                    break;
            }
            imageView.setImageMatrix(mMatrix);
            return true;
        }
    
        // 计算双指之间的距离
        private float distance(MotionEvent event) {
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return (float) Math.sqrt(x * x + y * y);
        }
    
        // 计算双指之间的中心点坐标
        private void midPoint(MotionEvent event) {
            float x0 = event.getX(0);
            float y0 = event.getY(0);
            float x1 = event.getX(1);
            float y1 = event.getY(1);
            midX = (x0 + x1) / 2;
            midY = (y0 + y1) / 2;
        }
    });
    

    这样修改后,应该能够解决图片首次触摸时自动放大的问题。

    评论

报告相同问题?

问题事件

  • 创建了问题 10月10日