AndroidStudio MotionEvent: обнаружить только ACTION_UP во втором представлении, начиная ACTION_DOWN в первом представлении - PullRequest
0 голосов
/ 09 декабря 2018

Решил, используя предложение Эмандта.Мое личное решение добавлено ниже.

Я использую Android Studio для этого.

Я искал решения, но не мог найти ничего похожего на это.

Я хочу знатьв котором ImageView действие UP выполняется при запуске действия DOWN в другом ImageView (чтобы в конечном итоге иметь возможность перетаскивать одно изображение поверх другого и привязывать его к той же позиции, получая положение изображения, которое я перетянул).

В моем примере есть два ImageViews с идентификатором imageView (слева) и imageView2 (справа).В моем примере я еще ничего не перетаскиваю, я просто хочу коснуться левого изображения, увидеть «Действие было завершено» в журнале и поднять палец на правое изображение, показывающее «Действие было выполнено2».

Я не знаю, легко ли это возможно.

Насколько я могу судить из тестирования, MotionEvent.ACTION_UP запускается только для ImageView, когда вы также нажали на него заранее.Поэтому, когда я выпускаю сверху imageView2, он показывает только «Действие было выполнено» с левого изображения.

Я задавался вопросом, возможно ли это, играя с return false, поскольку возвращаемое значение сообщает, используется ли ActionEvent, поэтому я подумал, что если UP-событие imageView возвращает false, возможно, оно действительно вызывает событие UP imageView2, нонет.(Либо полное недоразумение с моей стороны, либо он не распознает UP на втором, потому что он не начинался с DOWN, и MotionEvents, вероятно, всегда должны начинаться с DOWN).

public class MainActivity extends Activity {
ImageView imageView;
ImageView imageView2;
String DEBUG_TAG = "action";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imageView = findViewById(R.id.imageView);
    imageView2 = findViewById(R.id.imageView2);

    imageView.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            //int action = MotionEventCompat.getActionMasked(event);
            int action = event.getActionMasked();

            switch(action) {
                case (MotionEvent.ACTION_DOWN) :
                    Log.d(DEBUG_TAG,"Action was DOWN"+v.toString());
                    return true;
                case (MotionEvent.ACTION_MOVE) :
                    //Log.d(DEBUG_TAG,"Action was MOVE");
                    return true;
                case (MotionEvent.ACTION_UP) :
                    Log.d(DEBUG_TAG,"Action was UP"+v.toString());
                    return false;

                default :
                    //return true;
            }
            return true;
        }
    });

    imageView2.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            //int action = MotionEventCompat.getActionMasked(event);
            int action = event.getActionMasked();

            switch(action) {
                case (MotionEvent.ACTION_DOWN) :
                    Log.d(DEBUG_TAG,"Action was DOWN2"+v.toString());
                    return true;
                case (MotionEvent.ACTION_MOVE) :
                    //Log.d(DEBUG_TAG,"Action was MOVE");
                    return true;
                case (MotionEvent.ACTION_UP) :
                    Log.d(DEBUG_TAG,"Action was UP2"+v.toString());
                    return true;

                default :
                    //return true;
            }
            return true;
        }
    });
}

}

Если не существует простого способа сделать это, я подумываю решить это математически, но, возможно, некоторые из вас могут помочь.

Поэтому мой вопрос, есть ли способ распознать UP?действие над вторым ImageView, когда в данный момент он находится в MotionEvent другого ImageView?

SOLUTION (см. ответ emandt)

Я отказался от второго OnClickListener, потому что понял, что 2-е изображение не нуждается ни в какомМне просто нужна его позиция.

Добавил этот метод:

 @Nullable
private View getDroppedView(View droppedView, int x, int y, List<View> arrayOfPossibilities) {
    Rect cVisibleBoundsRect = new Rect();
    for (View cView : arrayOfPossibilities) {
        //if currently iterated view doesn't have values for getGlobalVisibleRect, skip the .contains part
        //ignore the item which is your current active item (which would potentially be dropped)
        //getGlobalVisibleRect sets cVisibleBoundsRect immediately to the Rect given as parameter
        if (!cView.getGlobalVisibleRect(cVisibleBoundsRect)||(cView.equals(droppedView))) continue;
        if (cVisibleBoundsRect.contains(x, y)) {
            Log.d(DEBUG_TAG,"Found something");
            //THIS "cView" IS THE VIEW WHERE YOU RELEASED THE FINGER
            return cView;
        }
    }
    Log.d(DEBUG_TAG,"Found nothing");
    return null;
}

И добавил это в onUP:

case (MotionEvent.ACTION_UP) :
                    View dropTarget;
                    Log.d(DEBUG_TAG,"Action was UP"+v.toString());
                    dropTarget = getDroppedView(v, (int)event.getRawX(), (int)event.getRawY(), listOfViews);

                   if (dropTarget != null){
                        v.setX(dropTarget.getX());
                        v.setY(dropTarget.getY());
                    }

1 Ответ

0 голосов
/ 10 декабря 2018

Я думаю, вы хотите знать, в каком представлении вы отпускаете палец с экрана, я прав?

Чтобы сделать это, вы можете использовать один и тот же «View.OnTouchListener ()» для всехваши Views и в ACTION_UP вы должны вызвать новый метод, похожий на этот (псевдокод):

....
case (MotionEvent.ACTION_UP) :
    View[] cArrayOfPossibileViews = new View[]{ findViewById(IMAGE_1), findViewById(IMAGE2) }
    getDroppedView(v, event.getRawX(), event.getRawY(), cArrayOfPossibileViews);
    break;
}
....

@Nullable
private View getDroppedView(View view, int x, int y, View[] arrayOfPossibilities) {
    Rect cVisibleBoundsRect = new Rect();
    for (View cView : arrayOfPossibilities) {
        if (!cView.getGlobalVisibleRect(cVisibleBoundsRect)) continue;
        if (cVisibleBoundsRect.contains(x, y)) {
            //THIS "cView" IS THE VIEW WHERE YOU RELEASED THE FINGER
            return cView;
        }
    }
    return null;
}

Этот метод получает View View и сравнивает их с значениями X и Y вашего Touch Event.Если X и Y содержатся внутри границ View, это означает, что View - это то, что вам нужно.

...