AndroidStudio MotionEvent:仅在第二个视图上检测到ACTION_UP,在第一个视图上开始检测ACTION_DOWN

时间:2018-12-09 11:20:40

标签: java android android-studio ontouchlistener motionevent

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

1 个答案:

答案 0 :(得分:0)

我想您想知道从屏幕上松开手指的视图是哪个,对吗?

为此,您可以对所有视图使用相同的“ View.OnTouchListener()”,并且在ACTION_UP中,您必须调用与此类似的新方法(伪代码):

  "columns": [
      {% for key, value in columns %}
      {% set result = '{{ key }}' %}
        {"data": "{{ result }}"},
        {% endfor %}
      { "data": "id" }
    ]

此方法获取视图范围,并在您的触摸事件的X和Y处进行比较。如果X和Y包含在View范围内,则表示View是您需要的视图。