簡體   English   中英

AndroidStudio MotionEvent:僅在第二個視圖上檢測到ACTION_UP,在第一個視圖上啟動ACTION_DOWN

[英]AndroidStudio MotionEvent: detect only ACTION_UP on a second view, starting ACTION_DOWN on first view

通過使用emandt的建議解決了該問題。 我的個人解決方案在下面添加。

我為此使用Android Studio。

我在尋找解決方案,但找不到類似的東西。

我想知道在另一個ImageView上開始執行DOWN動作時,在哪個ImageView上執行了UP動作(最終可以通過獲取拖動的圖像的位置,將一個圖像拖到另一個圖像上,並使其捕捉到相同的位置)。

我的示例有兩個ImageView,其ID為imageView(左)和imageView2(右)。 在我的示例中,我還沒有拖動任何東西,我只想觸摸左側的圖像,請在日志中看到“動作已按下”,然后將手指移到顯示“動作已向上2”的右側圖像上。

我不知道這是否容易實現。

據我從測試中得知,MotionEvent.ACTION_UP僅在您事先按下ImageView時才觸發。 因此,當我在imageView2頂部釋放時,它僅顯示左側圖像中的“操作已完成”。

我想知道是否可以通過使用return false來玩,因為返回值表明是否消耗了ActionEvent,所以我認為imageView的UP事件是否返回false,也許確實觸發了imageView2的UP事件,但沒有。 (或者我完全誤解了,或者第二次它不能識別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;
        }
    });
}

}

如果沒有簡單的方法可以做到這一點,那么我正在考慮數學上的解決方案,但是也許有些人可以提供幫助。

所以我的問題是,有一種方法可以識別當前在另一個ImageView的MotionEvent中的第二個ImageView上的UP動作嗎?

解決方案(請參閱Emandt的答案)

我放棄了第二個OnClickListener,因為我意識到第二張圖像不需要任何東西,只需要它的位置即可。

添加了此方法:

 @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());
                    }

我想您想知道從屏幕上松開手指的視圖是哪個,對嗎?

為此,您可以對所有視圖使用相同的“ View.OnTouchListener()”,並且在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;
}

此方法獲取視圖范圍,並比較它們在您的觸摸事件的X和Y范圍內。 如果X和Y包含在View范圍內,則表示View是您需要的視圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM