Gridview TouchListener только для видимых ячеек - PullRequest
0 голосов
/ 30 октября 2018

Я создаю игру. Я использую GridView для отображения игровых блоков различной формы (в стиле тетриса). Так, например, у меня есть блок L, блок T и т. Д.

Когда игрок касается и нажимает на блок, он может переместить его в любое место на экране. Каждый блок на самом деле является GridView, который имеет несколько цветных ячеек и несколько невидимых (зависит от формы блока).

ms paint image

Проблема возникает, когда блоки находятся рядом друг с другом, и вы хотите переместить блок, который находится «под» другими блоками. Из-за формы gridView касание в позиции 1 или 2 зеленого блока не вызовет слушателя касания зеленого блока, а синий (так как синий блок был помещен после зеленого на макете, и вы касаетесь его границ). Таким образом, игрок начнет перемещать синий блок, но, конечно, он хотел переместить зеленый.

Как я могу исправить эту проблему?

Edit:

Я пытался настроить сенсорный прослушиватель для каждого дочернего блока gridView (не обращайте внимания на пустые ячейки в данный момент) и передать информацию методам, которые я сделал. Тем не менее, ACTION_DOWN работает, но как только я двигаю пальцем, ACTION_UP срабатывает (без каких-либо ACTION_MOVE).

void setBlockTouchListener(final Block block)
{
    for (int i = 0; i < block.getChildCount(); i++)
    {
        block.getChildAt(i).setOnTouchListener(new View.OnTouchListener()
        {
            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                final int X = (int) event.getRawX();
                final int Y = (int) event.getRawY();
                switch (event.getAction() & MotionEvent.ACTION_MASK)
                {
                    case MotionEvent.ACTION_DOWN:
                        Log.d("TAG", "child down");
                        onDown(block, X, Y, MotionEvent.ACTION_DOWN);
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        Log.d("TAG", "child cancel");
                        onCancel(block, X, Y, MotionEvent.ACTION_CANCEL);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.d("TAG", "child move");
                        onMove(block, X, Y, MotionEvent.ACTION_MOVE);
                        break;
                }

                return true;
            }
        });
    }
}

Logcat (когда я пытаюсь коснуться и переместить блок):

child_down
child_cancel 

1 Ответ

0 голосов
/ 09 ноября 2018

Попробуйте позвонить requestDisallowInterceptTouchEvent после

case MotionEvent.ACTION_DOWN

Другим видом может быть кража сенсорных событий. Это запретит кражу.

Block block = ((Block) v.getParent());

switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        block.requestDisallowInterceptTouchEvent(true);
        onDown(block, X, Y, MotionEvent.ACTION_DOWN);
        break;
        }
...