繁体   English   中英

创建 2 个自定义视图时,Android 自定义视图上的 onTouchEvent 不起作用

[英]onTouchEvent on Android custom view doesn't work when 2 custom view are created

我的目标是在 Activity 中绘制 3 个等于自定义视图。 自定义视图覆盖 onTouchEvent。 如果我在活动中仅添加一个自定义视图,通过 XML 或以编程方式,一切正常。 如果我添加 2 个自定义视图(相同的自定义视图),则触摸事件仅适用于一个自定义视图,另一个在布局中是固定的,根本不会拦截任何内容。 我看过其他讨论,但我找不到问题。 我的自定义视图 class:

 public class IconCropView extends View {

//contants strings
private static final String TAG = "IconCropView";
private static final int TEXT_COLOR = Color.RED;
private static final float TEXT_SIZE = 30.0f;
private static final float STROKE_WIDTH = 4.0f;
//drawing objects
private Paint paint;
//text
private Paint textPaint;

//point objects
private Point[] points;
private Point start;
private Point offset;

//variable ints
private int altezzaMinima;
private int altezza;
private int halfCorner;
private int cornerColor;
private int edgeColor;
private int outsideColor;
private int corner = 30;

//variable booleans
private boolean initialized = false;

//drawables
private Drawable moveDrawable;
private Drawable  resizeDrawable2;
//context
Context context;

//Rect del canvas
Rect cropBorder;
boolean clickInCropRect;

public IconCropView(Context context) {
    super(context);
    this.context = context;
    init(null,null);
}

public IconCropView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    init(attrs,null);
}

public IconCropView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this.context = context;
    init(attrs,null);
}
public IconCropView(Context context, Point[] punti) {
    super(context);
    this.context = context;
    init(null,punti);
}


private void init(@Nullable AttributeSet attrs,Point[] punti ){


    paint = new Paint();
    start = new Point();
    offset = new Point();

    //initial dimensions
    altezzaMinima = 400;
    altezza = altezzaMinima;
    halfCorner = 25;

    //colors
    cornerColor = Color.BLACK;
    edgeColor = Color.WHITE;
    outsideColor =Color.parseColor("#00000088");

    //initialize corners;
    points = new Point[4];

    points[0] = new Point();
    points[1] = new Point();
    points[2] = new Point();
    points[3] = new Point();

    if(punti == null) {
        //init corner locations;
        //top left
        points[0].x = 0;
        points[0].y = 0;

        //top right
        points[1].x = 600;
        points[1].y = 0;

        //bottom left
        points[2].x = 0;
        points[2].y = altezzaMinima;

        //bottom right
        points[3].x = 600;
        points[3].y = altezzaMinima;
    }
    if(punti != null){
        //init corner locations;
        //top left

        points[0].x = punti[0].x;
        points[0].y = punti[0].y;

        //top right
        points[1].x = punti[1].x;
        points[1].y = punti[1].y;

        //bottom left
        points[2].x = punti[2].x;
        points[2].y = punti[2].y;

        //bottom right
        points[3].x = punti[3].x;
        points[3].y = punti[3].y;
    }
    //init drawables

    resizeDrawable2 = getResources().getDrawable(R.drawable.circle);

    //set initialized to true
    initialized = true;

    //inizializzo testo
    textPaint = new Paint();
    textPaint.setColor(TEXT_COLOR);
    textPaint.setTextSize(TEXT_SIZE);

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //set paint to draw edge, stroke
    if(initialized) {
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setColor(edgeColor);
        paint.setStrokeWidth(4);
        cropBorder = new Rect(points[0].x + halfCorner, points[0].y + halfCorner,points[0].x + halfCorner + 500,points[0].y + halfCorner + altezza);
        //crop rectangle
        canvas.drawRect(cropBorder, paint);
        //set paint to draw outside color, fill
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(outsideColor);
        resizeDrawable2.setBounds(points[2].x, points[2].y, points[2].x + halfCorner*2, points[2].y + halfCorner*2);
        //place corner drawable
        resizeDrawable2.draw(canvas);

    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    //return super.onTouchEvent(event);

    switch(event.getActionMasked()){
        case MotionEvent.ACTION_DOWN:{

            //get the coordinates
            start.x = (int)event.getX();
            start.y = (int)event.getY();

            //get the corner touched if any
            corner = getCorner(start.x, start.y);

            //get the offset of touch(x,y) from corner top-left point
            offset = getOffset(start.x, start.y, corner);

            //account for touch offset in starting point
            start.x = start.x - offset.x;
            start.y = start.y - offset.y;

            // dentro il rettangolo
            clickInCropRect = cropBorder.contains( start.x, start.y);
            break;

        }
        case MotionEvent.ACTION_MOVE:{
            if(corner == 0 || clickInCropRect ) {
                points[0].x = Math.max(points[0].x + (int) Math.min(Math.floor((event.getX() - start.x - offset.x)), Math.floor(getWidth() - points[0].x - 2*halfCorner - (cropBorder.width()))), 0);
                points[1].x = Math.max(points[1].x + (int) Math.min(Math.floor((event.getX() - start.x - offset.x)), Math.floor(getWidth() - points[1].x - 2*halfCorner)), altezza);
                points[2].x = Math.max(points[2].x + (int) Math.min(Math.floor((event.getX() - start.x - offset.x)), Math.floor(getWidth() - points[2].x - 2*halfCorner - (cropBorder.width()))), 0);
                points[3].x = Math.max(points[3].x + (int) Math.min(Math.floor((event.getX() - start.x - offset.x)), Math.floor(getWidth() - points[3].x - 2*halfCorner)), altezza);

                points[0].y = Math.max(points[0].y + (int) Math.min(Math.floor((event.getY() - start.y - offset.y)), Math.floor(getHeight() - points[0].y - 2*halfCorner - (cropBorder.height()) )), 0);
                points[1].y = Math.max(points[1].y + (int) Math.min(Math.floor((event.getY() - start.y - offset.y)), Math.floor(getHeight() - points[1].y - 2*halfCorner - (cropBorder.height()))), 0);
                points[2].y = Math.max(points[2].y + (int) Math.min(Math.floor((event.getY() - start.y - offset.y)), Math.floor(getHeight() - points[2].y - 2*halfCorner)), altezza);
                points[3].y = Math.max(points[3].y + (int) Math.min(Math.floor((event.getY() - start.y - offset.y)), Math.floor(getHeight() - points[3].y - 2*halfCorner)), altezza);

                start.x = points[0].x+(cropBorder.width()/2);
                start.y = points[0].y+(cropBorder.height()/2);
                Log.v("TOUCHED", points[0].x + " ");

                invalidate();

            }
            else if (corner == 2){
                altezza =  Math.min((Math.min((Math.max(altezzaMinima, (int)(altezza + Math.floor(event.getY()) - start.y - offset.y))), altezza + (getHeight() - points[2].y - 2* halfCorner ))), altezza + (getWidth() - points[1].x - 2* halfCorner ));
                points[2].y = points[0].y + altezza;
                points[3].y = points[0].y + altezza;
                points[3].x = points[0].x + altezza;
                points[1].x = points[0].x + altezza;
                start.y = points[2].y;
                invalidate();


            }
            break;

        }

    }
    return true;
}

private int getCorner(float x, float y){
    int corner = 5;
    for (int i = 0; i < points.length; i++){
        float dx = x - points[i].x;
        float dy = y - points[i].y;
        int max = halfCorner * 2;
        if(dx <= max && dx >= 0 && dy <= max && dy >= 0){
            return i;
        }
    }
    return corner;
}

private Point getOffset(int left, int top, int corner){
    Point offset = new Point();
    if(corner == 5){
        offset.x = 0;
        offset.y = 0;
    }else{
        offset.x = left - points[corner].x;
        offset.y = top - points[corner].y;
    }
    return offset;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

  }

在 onCreate 活动中:

    IconCropView iconCrop1 = new IconCropView(context);
    IconCropView iconCrop2 = new IconCropView(context,punti);
    RelativeLayout myLayout = findViewById(R.id.myLayout);
    myLayout .addView(iconCrop1);
    myLayout .addView(iconCrop2);

我也将它们放在 XML 文件中,但结果是一样的。

我会感谢你的帮助。

谢谢你们。

我解决了这个问题。 问题不在于 onTouchEvent,而是在其中定义 IconCropView 的容器。在我简单地定义一个元素并将其添加到布局之前。 现在我认为正确的方法是:

  1. 定义创建 IconCropView 的布局。它应该大于 IconCropview 否则它不能通过触摸移动:

RelativeLayout.LayoutParams 参数 = new RelativeLayout.LayoutParams(mImageViewWidth, mImageViewHeight / 4 );

  1. 定义与其容器相关的 IconCropView 边距。

params.setMargins(marginLeft,marginTop,marginRight,marginBottom);

3)创建新的 IconCropView 并将其添加到父布局活动中。 Mlayout是activity的主要布局:

IconCropView cropView = new IconCropView(context, width, height);

cropView .setLayoutParams(params);

mLayout.addView(cropView);

我希望这对某人有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM