Перемещение событий ПОСЛЕ длительного нажатия

#android #listener #gesturedetector

#Android #прослушиватель #gesturedetector

Вопрос:

Как я могу прослушать события перемещения после вызова длительного нажатия в моем GestureDetector?

Когда пользователь нажимает длинным нажатием, он запускает режим выбора и может перетащить квадрат на экран. Но я заметил, что onScroll не вызывается после использования LongPress.

Комментарии:

1. Как насчет onFling события от GestureDetector — вызывается ли оно после поднятия пальца вверх при длительном нажатии и перемещении? В качестве альтернативы вы также можете попробовать «raw» onTouchEvent

2. используете ли вы LongPress? вы можете принять событие длительного нажатия, но затем вернуть false, позволяя обрабатывать событие чему-либо выше. Существует также возможность отключить длительное нажатие в представлении, когда вы его поймаете.

3. @Dr.J к сожалению, LongPress не может быть использован. Метод возвращает значение void, а не boolean

4. обработчик жестов возвращает логическое значение, когда он использует события onMove с достаточно высокой скоростью, чтобы вызвать событие onFling.

Ответ №1:

Некоторое время пытался бороться с этим, и на данный момент решение таково:

  1. Отключите длительное нажатие, используя setIsLongpressEnabled (isLongpressEnabled) на вашем детекторе жестов

Вот мой метод onTouch, на мой взгляд:

 public boolean onTouchEvent(MotionEvent event) {
        if (mGestureDetector.onTouchEvent(event)== true)
        {
            //Fling or other gesture detected (not logpress because it is disabled)
        }
        else
        {
            //Manually handle the event.
            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
                //Remember the time and press position
                Log.e("test","Action down");
            }
            if (event.getAction() == MotionEvent.ACTION_MOVE)
            {
                //Check if user is actually longpressing, not slow-moving 
                // if current position differs much then press positon then discard whole thing
                // If position change is minimal then after 0.5s that is a longpress. You can now process your other gestures 
                Log.e("test","Action move");
            }
            if (event.getAction() == MotionEvent.ACTION_UP)
            {
                //Get the time and position and check what that was :)
                Log.e("test","Action down");
            }

        }
        return true;
    }
  

Мое устройство возвращало ACTION_MOVE всякий раз, когда я держу палец на экране. Если у вас этого не происходит, просто проверьте состояние какого-либо нажатого флага через 0,5 с, используя таймер или поток.

Надеюсь, это поможет!

Ответ №2:

Я выполнил эту задачу, используя следующие концепции:

Предположим, у меня есть вид изображения, и при длительном нажатии на него изображение внутри этого вида изображения можно было бы перетаскивать и размещать внутри другого вида (например, относительного макета), установленного MyClickListner в методе setOnLongClickListener() представления изображения.

  private final class MyClickListener implements View.OnLongClickListener {

    // called when the item is long-clicked
    @Override
    public boolean onLongClick(View view) {
        // TODO Auto-generated method stub

        // create it from the object's tag
        ClipData.Item item = new ClipData.Item((CharSequence)view.getTag());

        String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN };
        ClipData data = new ClipData(view.getTag().toString(), mimeTypes, item);
        View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);

        view.startDrag( data, //data to be dragged
                shadowBuilder, //drag shadow
                view, //local data about the drag and drop operation
                0   //no needed flags
        );
        //  view.setVisibility(View.INVISIBLE);
        return true;
    }
}
  

Затем установите MyDragListner в относительном расположении (например, bigImageRelativeLayoutVw.setOnDragListener(новый MyDragListener());)

  class MyDragListener implements View.OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {

        int X=(int)event.getX();
        int Y=(int)event.getY();
        int touchX = 0,touchY=0;
        // Handles each of the expected events
        switch (event.getAction()) {

            //signal for the start of a drag and drop operation.
            case DragEvent.ACTION_DRAG_STARTED:
                // do nothing
                break;

            //the drag point has entered the bounding box of the View
            case DragEvent.ACTION_DRAG_ENTERED:


                break;

            //the user has moved the drag shadow outside the bounding box of the View
            case DragEvent.ACTION_DRAG_EXITED:
                //    v.setBackground(normalShape); //change the shape of the view back to normal
                break;

            //drag shadow has been released,the drag point is within the bounding box of the View
            case DragEvent.ACTION_DROP:
                // if the view is the bottomlinear, we accept the drag item
                if(v == bigImageRelativeLayoutVw) {
                    View view = (View) event.getLocalState();


                    touchX=X-viewCoords[0]-20;
                    touchY=Y-viewCoords[1]-20;


                    View view1=new View(getActivity());
                    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(30,30);

                    layoutParams.leftMargin =touchX;
                    layoutParams.topMargin = touchY;


                  view1.setBackgroundResource(R.drawable.heavy_damage);




                    view1.setLayoutParams(layoutParams);
                    RelativeLayout containView = (RelativeLayout) v;
                    containView.addView(view1);


                    view.setVisibility(View.VISIBLE);

                } else {
                    View view = (View) event.getLocalState();
                    view.setVisibility(View.VISIBLE);

                    break;
                }
                break;

            //the drag and drop operation has concluded.
            case DragEvent.ACTION_DRAG_ENDED:
                //     v.setBackground(normalShape);    //go back to normal shape

            default:
                break;
        }
        return true;
    }
}