TableRow 中多个 TextView 的 onTouchListener [英] onTouchListener for multiple TextViews inside TableRow

查看:81
本文介绍了TableRow 中多个 TextView 的 onTouchListener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我已经连续搜索了几个小时,但没有找到任何适合我的问题的解决方案.

Up till now I have searched for hours on end and have not found any suitable solution to my issue.

我正在摆弄我的 android 应用程序并尝试制作数独游戏.

Am fiddling around with my android application and trying to make a Sudoku game.

TableLayout 由 9 个 TableRow 组成,每个 TableRow 包含 9 个 TextView.因此 9*9 网格包含 81 个 TextView,每个都有一个 OnTouchListener:

The TableLayout consists of 9 TableRows, each containing 9 TextViews. Thus the 9*9 grid contains 81 TextViews each having a OnTouchListener:

final OnTouchListener cellTouch = new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent e) {
        Log.d("TOUCH", "id: "+v.getId() + " "+e.toString());

        final int action = e.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                // set background to different colour
                // set background back if this is different TextView

                break;
            }
            case MotionEvent.ACTION_MOVE: {

                break;
            }               
        }

        return true;
    }       
};

OnTouch 在每个单独的 TextView 上被触发,但在触摸一个并在以下位置移动轨迹球后发生:

The OnTouch gets fired on each individual TextView, but after touching one and moving the trackball around the following occurs:

  • ACTION_DOWN
  • ACTION_MOVE 的数量
  • ACTION_UP

但是,我想要的是 OnTouch 来触发其他 TextViews 并使它们突出显示.我创建单元格的方式如下所示:

However, what I would like is the OnTouch to fire on the other TextViews and make them highlighted. The way I create a cell is shown below:

            TextView cellLabel = (TextView) inflater.inflate(R.layout.sudoku_cell, tr, false);
            cellLabel.setId(curCellId);
            cellLabel.setText(""+ curCellId);

            cellLabel.setOnTouchListener(cellTouch);
            cellLabel.setOnFocusChangeListener(cellFocus);
            cellLabel.setOnClickListener(cellClick);
            cellLabel.setFocusable(true);
            cellLabel.setClickable(true);
            cellLabel.setFocusableInTouchMode(true);

每个单独的单元格:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="35dp"
android:layout_weight="1"
android:textSize="18dp"
android:textColor="#FFFFFF"
android:gravity="center"
android:background="@layout/border"
/>

我一直在尝试很多不同的东西.例如确定 TextView 指针在顶部,但没有任何运气.

I have been trying so many different things. Such as determining the TextView the pointer is on top, but with out any luck.

希望你们有想法.感谢您抽出宝贵时间.

Hope any of you have an idea. Thank you for your time.

亲切的问候.

编辑

搜索函数循环遍历 TextView[][] 并找到合适的单元格.但是,仅适用于行.如果我从一行切换到另一行,则不起作用.

The search function to loop through the TextView[][] and find the appropriate cell. However, only works on a row basis. If I switch from one row to the other it does not work.

private TextView getCell (View v, MotionEvent e) {
    float x = e.getX();
    float y = e.getY();

    for (int i = 0; i < GRID_HEIGHT; i++) {
        for (int j = 0; j < GRID_WIDTH; j++) {
            TextView tv = tvGrid[i][j];

            Rect rectView = new Rect(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());         

            if(rectView.contains((int)x, (int)y)) {
                return tv;
            }
        }
    }

    return null;
}

推荐答案

这是我自己试过的代码:

Here's the code I tried myself:

布局只是一个带有 3 个 TableRow 的 TableLayout,每个 TableRow 包含 3 个 TextView,id 为 t1, t2, .., t9

The layout is just a TableLayout with 3 TableRows, and each TableRow contains 3 TextViews with ids like t1, t2, .., t9

还有活动:

public class ImgActivity extends Activity {

protected Map<View, Rect> cells = new HashMap<View, Rect>();

protected boolean hasCoordinatesPopulated;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    final TableLayout table = (TableLayout) findViewById(R.id.table);
    table.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (!hasCoordinatesPopulated) {
                View view = table.findViewById(R.id.t1);
                Rect rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t2);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t3);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t4);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t5);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t6);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t7);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t8);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                view = table.findViewById(R.id.t9);
                rect = getRawCoordinatesRect(view);
                cells.put(view, rect);

                hasCoordinatesPopulated = true;
            }
        }

        private Rect getRawCoordinatesRect(final View view) {
            int[] coords = new int[2];
            view.getLocationOnScreen(coords);
            Rect rect = new Rect();
            rect.left = coords[0];
            rect.top = coords[1];
            rect.right = rect.left + view.getWidth();
            rect.bottom = rect.top + view.getHeight();
            return rect;
        }
    });
    table.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(final View v, final MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
                final int x = (int) event.getRawX();
                final int y = (int) event.getRawY();
                for (final Entry<View, Rect> entry : cells.entrySet()) {
                    final View view = entry.getKey();
                    final Rect rect = entry.getValue();
                    if (rect.contains(x, y)) {
                        view.setBackgroundColor(Color.CYAN);
                    } else {
                        view.setBackgroundColor(Color.TRANSPARENT);
                    }
                }
                return true;
            }
            return false;
        }
    });
}

}

当然,这是一个快速的样本变体.您可以将上次选择的视图存储在单独的字段中(以在移动时取消选择),当找到指针下方的元素时,只需 break 循环即可节省一些时间.

Of course it's a quick sample variant. You can store your last selected view in a separate field (to deselect on move) and when element below the pointer is found, just break the loop saving some time.

这篇关于TableRow 中多个 TextView 的 onTouchListener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆