将 MotionEvent 值存储在 ArrayList 中

Store MotionEvent values in an ArrayList

大家好,

所以我在自定义视图中使用 onDraw class 在 RelativeLayout + TableLayout 上绘制形状,一切正常。

MotionEventACTION_MOVE 中,我将 X & Y 传递到我的 CustomView 并调用一个方法,该方法 returns 每组坐标的唯一 ID 值 /形状分别。

由于将我的手指从一个形状拖动到另一个形状:多个值将按预期返回到控制台,我想将这些值存储在 Array 中以备将来使用。我遇到的问题是,当我尝试存储值时,它只在控制台显示 4 的情况下存储一个值。

控制台输出如下:

06-22 07:28:56.173 zar.myapp I/System.out: value: 354

06-22 07:28:56.193 zar.myapp I/System.out: value: 858

06-22 07:28:56.213 zar.myapp I/System.out: value: 989

06-22 07:28:56.213 zar.myapp I/System.out: value: 789

代码:

ArrayList XYcoords  = new ArrayList();

switch (event.getAction()) {
 case MotionEvent.ACTION_DOWN:
   
 return true;
 case MotionEvent.ACTION_MOVE:

  ///Single value for each finger movement.
   DotView endView = getChildForTouch((TableLayout) v, x, y); 

   XYcoords.add(endView.getId() );

 break;

 case MotionEvent.ACTION_UP:
    ///I tried adding them from here as well.

 ///When I check the size of `XYcoords` it allways return 1
 System.out.println("Array Size: " + XYcoords.size());

 break;

DotView class: 在我的 MainActivity 中构建我的 table 网格 我调用:Dotview.setId(i); 分配一个每个单元格的唯一 ID(已验证)。 (我只分享了相关代码):

private static class DotView extends View {

        private static final int DEFAULT_SIZE = 100;
        private Paint mPaint = new Paint();
        private Rect mBorderRect = new Rect();
        private Paint mCirclePaint = new Paint();
        private int mRadius = DEFAULT_SIZE / 4;
        int id;

        public DotView(Context context) {
            super(context);
            mPaint.setStrokeWidth(2.0f);
            mPaint.setStyle(Style.STROKE);
            mPaint.setColor(Color.RED);
            mCirclePaint.setColor(Color.CYAN);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.parseColor("#0099cc"));
            mBorderRect.left = 0;
            mBorderRect.top = 0;
            mBorderRect.right = getMeasuredWidth();
            mBorderRect.bottom = getMeasuredHeight();
            canvas.drawRect(mBorderRect, mPaint);
            canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2,
                    mRadius, mCirclePaint);
        }

        
        public void setId(Int id){
            this.id = id;
        }
        public int getId()
        {
            return this.id;
        }

    }

getChildForTouch

private DotView getChildForTouch(TableLayout table, float x, float y) {
                    final int childWidth = ((TableRow) table.getChildAt(0))
                            .getChildAt(0).getWidth();
                    final int childHeight = ((TableRow) table.getChildAt(0))
                            .getChildAt(0).getHeight();


                    // find out the row of the child
                    int row = 0;
                    do {
                        if (y > childHeight) {
                            row++;
                            y -= childHeight;
                        } else {
                            break;
                        }
                    } while (y > childHeight);
                    int column = 0;
                    do {
                        if (x > childWidth) {
                            column++;
                            x -= childWidth;
                        } else {
                            break;
                        }
                    } while (x > childWidth);
                    return (DotView) ((TableRow) table.getChildAt(row))
                            .getChildAt(column);
                }

可根据要求提供更多代码。

提前致谢

The issue I am having is that when I try to store the values, it only stores one value in a case where the console shows 4

我假设您正在 onTouch() 回调中创建 XYcoords 列表,在这种情况下,它的大小为 1,对应于当前触摸事件。当用户移动他的手指 onTouch() 时,另一个触摸事件将再次调用,此时您将创建一个 new XYcoords 列表,其中包含一个条目等等...

要解决这个问题,请将 XY 坐标列表初始化 移到 onTouch() 回调的 之外,就像 class 中的一个字段一样。这样您就不会在每次发生触摸事件时都重新创建它。

附带说明一下,我假设您使用当前代码尝试将用户移动手指时触摸的 DotView 存储在列表中。在这种情况下,您很可能不想简单地在 MotionEvent.ACTION_MOVE 中执行 XYcoords.add(endView.getId()) 因为您最终会得到数百个重复条目(因为会有将在单个 DotView 中触发的大量触摸事件)。相反,不允许重复:

if (XYcoords.size() != 0) {
   // check to see if we aren't trying to add the same DotView reference
   // (meaning we are still inside the same DotView)
   int lastId = XYcoords.get(XYcoords.size() - 1);
   if (lastId != endView.getId()) {
      // not the same DotView so add it
      XYcoords.add(endView.getId());
   } 
} else {
   XYcoords.add(endView.getId()); // first event, must add it
}

在 MotionEvent.ACTION_UP 的情况下,您需要使用(或将 XY 坐标中的信息存储在其他地方)XY 坐标中的数据并 清除它 所以下次用户开始触摸 DotViews 你有一个新的历史记录(XY 坐标中没有项目)。