MotionEvent.ACTION_MOVE 在 Android 中不起作用

Posted

技术标签:

【中文标题】MotionEvent.ACTION_MOVE 在 Android 中不起作用【英文标题】:MotionEvent.ACTION_MOVE Not Work In Android 【发布时间】:2012-08-31 17:23:49 【问题描述】:

在我的 android 应用程序中,我有一个裁剪图像。所以,我编写了一个扩展ImageViewCropBox。我想移动裁剪框并调整其大小。我使用OnTouchListener,但 MotionEvent.ACTION_MOVE 不起作用。我用谷歌搜索,但我什么也没找到。

属性类:

public class Attr 

    public static final float CROP_BOX_START_X = 5;
    public static final float CROP_BOX_START_Y = 5;
    public static final float CROP_BOX_END_X = 305;
    public static final float CROP_BOX_END_Y = 105;


CropBox 类:

public class CropBox extends ImageView 

    private Paint paint = new Paint();


    public CropBox(Context context) 
        super(context);
    

    public CropBox(Context context, AttributeSet attributeSet) 
        super(context, attributeSet);
    


    @Override
    public void onDraw(Canvas canvas) 
        float[][] circleXY = 
            Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y,
            (Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X) / 2, Attr.CROP_BOX_START_Y,
            Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y,
            Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y,
            (Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X) / 2, Attr.CROP_BOX_END_Y,
            Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y,
            Attr.CROP_BOX_START_X, (Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y) / 2,
            Attr.CROP_BOX_END_X, (Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y) / 2
        ;
        float[][] lineXY = 
            Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y,
            Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y,
            Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y,
            Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y
        ;

        paint.setColor(Color.CYAN);
        paint.setStrokeWidth(1);

        for(int i = 0 ; i < circleXY.length ; i++)
            canvas.drawCircle(circleXY[i][0], circleXY[i][1], 5, paint);

        paint.setStrokeWidth(2);

        for(int i = 0 ; i < lineXY.length ; i++)
            canvas.drawLine(lineXY[i][0], lineXY[i][1], lineXY[i][2], lineXY[i][3], paint);
    


CropTestActivity 类:

public class CropTestActivity extends Activity 

    private ImageView imageView;
    private CropBox cropBorder;
    private RelativeLayout relativeLayout;
    private RelativeLayout.LayoutParams layoutParams;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.crop_test_layout);
        imageView = (ImageView)findViewById(R.id.android_image);
        cropBorder = new CropBox(this);
        relativeLayout = (RelativeLayout)findViewById(R.id.crop_test_layout);
        layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
        ViewTreeObserver viewTreeObserver = imageView.getViewTreeObserver();
        if(viewTreeObserver.isAlive()) 
            viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
                public void onGlobalLayout() 
                    layoutParams.leftMargin = imageView.getWidth() / 2 - (int)((Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X) / 2) + imageView.getLeft();
                    layoutParams.topMargin = imageView.getHeight() / 2 - (int)((Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y) / 2) + imageView.getTop();
                
            );
        
        relativeLayout.addView(cropBorder, layoutParams);
        cropBorder.setOnTouchListener(new Crop());
    


作物类别:

public class Crop implements OnTouchListener 

    private static final int NONE = 0;
    private static final int BOX_DRAG = 1;
    private static final int BORDER_DRAG = 2;

    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();

    private PointF start = new PointF();

    private int mode = NONE;

    private float cropBoxStartX = Attr.CROP_BOX_START_X;
    private float cropBoxStartY = Attr.CROP_BOX_START_Y;
    private float cropBoxEndX = Attr.CROP_BOX_END_X;
    private float cropBoxEndY = Attr.CROP_BOX_END_Y;

    public boolean onTouch(View view, MotionEvent event) 
        CropBox cropBox = (CropBox)view;

        switch(event.getAction() & MotionEvent.ACTION_MASK) 

            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                start.set(event.getX(), event.getY());
                if(event.getX() > cropBoxStartX && event.getX() < cropBoxEndX && event.getY() > cropBoxStartY && event.getY() < cropBoxEndY)
                    mode = BOX_DRAG;
                else if(event.getX() == cropBoxStartX || event.getX() == cropBoxEndX || event.getY() == cropBoxStartY || event.getY() == cropBoxEndY)
                    mode = BORDER_DRAG;
                else
                    mode = NONE;
                break;

            case MotionEvent.ACTION_UP:
                mode = NONE;
                break;

            case MotionEvent.ACTION_MOVE:
                if(mode == BOX_DRAG) 
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
                
                else if(mode == BORDER_DRAG)   
                
                break;
        
        cropBox.setImageMatrix(matrix);
        return true;
    


布局 XML:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/crop_test_layout"
    android:layout_
    android:layout_ >

    <ImageView
        android:id="@+id/android_image"
        android:src="@drawable/android"
        android:layout_
        android:layout_
        android:layout_marginTop="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="10dp"
        android:layout_gravity="center"
        android:scaleType="fitXY"
        android:contentDescription="@string/android_image_description" >
    </ImageView>

</RelativeLayout>

感谢您的帮助。

【问题讨论】:

【参考方案1】:

我相信您的实现是正确的,我唯一没有看到的是您将 CropBox 的比例类型设置为 MATRIX 以便能够使用 setImageMatrix。

【讨论】:

实际上我忘记将比例类型设置为矩阵。但它还没有工作。

以上是关于MotionEvent.ACTION_MOVE 在 Android 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

检查是不是执行了 MotionEvent.ACTION_MOVE

Android事件分发机制理解

Canvas 停止识别痕迹 Android

在安卓设备中移动手指时找到正确的方向

一个可以跟随手指移动的PopupWindow

这RecyclerView的特效,谁看了不说6