Android onInterceptTouchEvent,在ViewGroup中获取子项

时间:2015-07-29 19:55:58

标签: android android-view viewgroup

我有像这样的布局(如棋盘),其中包含单元格(按钮)

| A | B | C | D |
-----------------
| E | F | G | H |
-----------------
| I | J | K | L |
-----------------
| X | Y | Z | W |

我正在以编程方式添加单元格,它们包含我设置的字母。

public void addCells(String letters){
    removeAllViews();
    int let = 0;
    for (int j = 0; j < 4; j++){
        for (int i = 0; i < 4; i++){
            String currentLetter = ""+letters.charAt(let);
            //Cell object that contains it's position and letter.
            Cell cell_ = new Cell(this.getContext(), new Point(i , j), new Letter(currentLetter)); 
            this.addView(cell_);
            this.cells[i][j] = cell_;
            let++;
        }
    }
}

我的目标是通过手指移动来连接细胞:

enter image description here

我正在从true返回onTouchEvent(),因此我可以捕获ViewGroup中的所有触摸onInterceptTouchEvent()

public boolean onTouchEvent(MotionEvent motionEvent) {
    return true;
}

但我无法得到逻辑。如何通过在该ViewGroup中单击/触摸来访问某个子对象?

当我点击'A'字母时,我想访问该单元格对象。

1 个答案:

答案 0 :(得分:1)

一般来说:

  • 父视图拦截所有触摸事件(x,y)

    onInterceptTouchEvent() { return true; }
    
  • 在触摸事件中,父级查找与事件位置匹配的内部视图

    onTouchEvent() { // see below }
    
  • 对该视图执行操作(点亮,更新数据等)

父母如何找到内部视图?

你可以通过两种方式实现,

1)具有对单元格视图的引用的板的数据结构([] [])。然后你知道什么是触摸事件X,Y所以如果所有单元格相等,只需根据单元格大小和位置计算正确的单元格。

View[][] board;
// Add the Views to the board in creation loop

int cellWidth = board[0][0].getMeasuredWidth();
int cellHeight = board[0][0].getMeasuredHeight();

int tragetX = (int)(x / cellWidth);
int targetY = (int)(y / cellHeight);

View targetCell = board[targetX][targetY];

// Do something with targetCell

2)迭代所有父子项(最后一个是最好的),并计算父位置内的子视图位置,并结合它的大小来确定该子项是否是目标。

View targetChild = null;
int[] loc = new int[2];
for (int i = getChildCount()-1; i >= 0; i--) {
    View child = getChildAt(i);
    child.getLocationInWindow(loc);
    if (x >= loc[0] && x <= loc[0]+child.getMeasuredWidth() &&
        y >= loc[1] && y <= loc[1]+child.getMeasuredHeight()) {
        targetChild = child;
        break;
    }
}
// Do something with targetChild

上面是一个例子,请写一个更好的代码:)(重用loc等等)