AndroidStudio MotionEvent:仅在第二个视图上检测到ACTION_UP,在第一个视图上启动ACTION_DOWN [英] AndroidStudio MotionEvent: detect only ACTION_UP on a second view, starting ACTION_DOWN on first view

查看:109
本文介绍了AndroidStudio MotionEvent:仅在第二个视图上检测到ACTION_UP,在第一个视图上启动ACTION_DOWN的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用emandt的建议解决了该问题.我的个人解决方案在下面添加.

Solved it by using emandt's suggestion. My personal Solution added below.

我正在为此使用Android Studio.

I'm using Android Studio for this.

我搜索了解决方案,但找不到类似的东西.

I searched for solutions but couldn't find anything resembling this.

我想知道在另一个ImageView上开始执行DOWN动作时,在哪个ImageView上发生了UP动作(最终能够通过获取图像的位置将一个图像拖到另一个图像上并使其捕捉到相同的位置我拖了过去.)

I want to know on which ImageView an UP action occurs while starting the DOWN action on a different ImageView (to eventually be able to drag one image over the other and make it snap to the same position by getting the position of the image I dragged over).

我的示例有两个ImageView,其ID为imageView(左)和imageView2(右). 在我的示例中,我还没有拖动任何东西,我只想触摸左侧的图像,请在日志中看到动作已按下",然后将手指移到显示动作已向上2"的右侧图像上.

My example has two ImageViews with the id imageView (left) and imageView2(right). In my example I'm not dragging anything yet, I just want to touch the left image, see "Action was down" in the log and lift the finger over the right image showing "Action was up2".

我不知道这是否容易实现.

I don't know if this is easily possible.

据我从测试中得知,MotionEvent.ACTION_UP仅在您事先按下ImageView时才触发.因此,当我在imageView2顶部释放时,它仅从左侧图像显示操作已完成".

As far as I can tell from testing, the MotionEvent.ACTION_UP only fires for an ImageView when you also pressed down on it beforehand. So when I release on top of imageView2 it only shows "Action was up" from the left image.

我想知道是否可以通过使用return false来玩,因为返回值表明是否消耗了ActionEvent,所以我认为imageView的UP事件是否返回false,也许确实触发了imageView2的UP事件,但没有. (要么是我完全误解,要么是第二次不能识别UP,因为它不是以DOWN开头,MotionEvents可能总是以DOWN开头.)

I wondered if it was possible by playing with return false, since the return value tells if an ActionEvent is consumed so I thought if the UP event of imageView returns false, maybe it does trigger the UP event of imageView2 but no. (Either complete misunderstanding on my part or it doesn't recognise UP on the second because it didn't start with a DOWN and MotionEvents probably always have to start with a 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;
        }
    });
}

}

如果没有简单的方法可以做到这一点,那么我正在考虑数学上的解决方案,但是也许有些人可以提供帮助.

If there is no simple way to do this, I'm thinking about solving this mathematically, but maybe some of you can help.

所以我的问题是,有一种方法可以识别当前在另一个ImageView的MotionEvent中的第二个ImageView上的UP动作吗?

So my question is, is there a way to recognise an UP action on a second ImageView while currently being in a MotionEvent of another ImageView?

我放弃了第二个OnClickListener,因为我意识到第二张图像不需要任何东西,我只需要它的位置即可.

I ditched the second OnClickListener because I realised that the 2nd image doesn't need any, I just need its position.

添加了此方法:

 @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中:

And added this in 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());
                    }

推荐答案

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

I think you want to know which is the View where you release the finger from the screen, am I right?

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

To do this you can use the same "View.OnTouchListener()" for all of your Views and in the ACTION_UP you have to call a new method similar to this (pseudo-code):

....
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边界,并在您的触摸事件的X和Y处进行比较.如果X和Y包含在View范围内,则表示View是您需要的视图.

This method get View bounds and compare them avains X and Y of your Touch Event. If X and Y are contained inside a View bounds it means that View is the one you need.

这篇关于AndroidStudio MotionEvent:仅在第二个视图上检测到ACTION_UP,在第一个视图上启动ACTION_DOWN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆