23

如果用户触摸视图 A 并拖动到视图 B 的底部,我如何检测触摸事件。我想检测视图 B 中的触摸事件。

我在视图 B 中添加了触摸侦听器,但如果用户最初触摸 A 并拖动到 B 上,则不会收到事件。

在此处输入图像描述

4

7 回答 7

66

您可以使用下面的代码来实现您的请求:

测试视图边界的方法(在下面的代码中使用)

    Rect outRect = new Rect();
    int[] location = new int[2];

    private boolean isViewInBounds(View view, int x, int y){
        view.getDrawingRect(outRect);
        view.getLocationOnScreen(location);
        outRect.offset(location[0], location[1]);
        return outRect.contains(x, y);
    }

用两个测试TextView

    final TextView viewA = (TextView)  findViewById(R.id.textView);
    final TextView viewB = (TextView)  findViewById(R.id.textView2);

设置视图A

OnClickListener需要保持OnTouchListener活动状态,直到ACTION_UP

    viewA.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {}
    });

    viewA.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int x = (int)event.getRawX();
            int y = (int)event.getRawY();
            if(event.getAction() == MotionEvent.ACTION_UP){
                if(isViewInBounds(viewB, x, y))
                    viewB.dispatchTouchEvent(event);
                else if(isViewInBounds(viewA, x, y)){
                    Log.d(TAG, "onTouch ViewA");
                    //Here goes code to execute on onTouch ViewA
                }
            }
            // Further touch is not handled
            return false;
        }
    });

设置视图B

仅当您还想按下 viewB 并拖动到 viewA 时才需要这样做

    viewB.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {}
    });

    viewB.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int x = (int)event.getRawX();
            int y = (int)event.getRawY();
            if(event.getAction() == MotionEvent.ACTION_UP){
                if(isViewInBounds(viewA, x, y))
                    viewA.dispatchTouchEvent(event);
                else if(isViewInBounds(viewB, x, y)){
                    Log.d(TAG, "onTouch ViewB");
                    //Here goes code to execute on onTouch ViewB
                }
            }
            // Further touch is not handled
            return false;
        }
    });

问候。

于 2012-11-22T02:42:08.810 回答
1

我确定您需要ViewGroup.dispatchTouchEvent(MotionEvent ev)在包含视图 A 和 B 的 ViewGroup 中覆盖方法。原始实现在容器接收时定义目标视图MotionEvent.getAction() == MotionEvent.ACTION_DOWN,然后将所有以下触摸事件分派到目标视图,直到收到MotionEvent.getAction() == MotionEvent.ACTION_UPMotionEvent.ACTION_CANCEL

在您的情况下,目标视图是 A 或容器本身(取决于您的容器onInterceptTouchEvent(MotionEvent ev)方法实现)。因此,您应该覆盖此类行为并将触摸事件不仅发送到目标视图,而且还发送到触摸区域下的所有视图(例如视图 B)。

如果您有兴趣,可以分享代码示例,我会尽力帮助您。

于 2012-10-19T18:34:06.557 回答
1

如果您从视图 A 的 onTouchEvent 返回 true,则不会传播该事件。在这种特殊情况下,当 A 低于 B 时,从视图 A 的 onTouch 返回 false。

如果您可以发布一些代码,这也会有所帮助。

于 2012-11-16T04:53:51.460 回答
1

View A中,覆盖onTouchEvent如下:

@Override
public boolean onTouchEvent(MotionEvent event) 
{

    float x = event.getRawX();
    float y = event.getRawY();
    if ( (B.getLeft() <= x <= B.getRight()) &&
         (B.getTop() <= y <= B.getBottom())
       )
    {
        Log.i("A", "Motion Event is currently above B");
        B.dispatchTouchEvent(event);
    }

    return true;
}

View B中,覆盖相同的方法,确保返回 false

@Override
public boolean onTouchEvent(MotionEvent event) 
{
    //TODO handle touch event
    return false;//this will allow A to continue using the event
}
于 2012-11-19T18:27:07.477 回答
0

尝试使用拖放框架。

于 2012-10-19T18:32:40.193 回答
0

当您在视图 B 上时,onTouch手动调用它。

if (viewBRect.contains(x, y)) {
    viewBsonTouch(view, motionEvent);
}
于 2012-11-15T12:32:47.190 回答
0

当用户从视图 B 抬起手指时,如何调用圆形菜单创建状态。下面是示例代码
circleMenu = findViewById(R.id.circle_menu);

    circleMenu.setMainMenu(Color.parseColor("#CDCDCD"), R.color.acik_yesil, 
    R.color.kirmizi)
                .addSubMenu(Color.parseColor("#258CFF"), R.drawable.add)
                .addSubMenu(Color.parseColor("#FF0000"), R.drawable.mul)
                .addSubMenu(Color.parseColor("#6d4c41"), R.drawable.sub)
                .addSubMenu(Color.parseColor("#FF077D8F"), R.drawable.div)
                .setOnMenuSelectedListener(new OnMenuSelectedListener() {
                    @Override
                    public void onMenuSelected(int index) {
                       
                        switch (index) {
                            case 0:
                                Toast.makeText(MainActivity.this, "add", 
      Toast.LENGTH_SHORT).show();
                                break;
                            case 1:
                                Toast.makeText(MainActivity.this, "mul", 
      Toast.LENGTH_SHORT).show();
                                break;
                case 2:
                                Toast.makeText(MainActivity.this, "sub", 
            Toast.LENGTH_SHORT).show();
                                break; 
                case 3:
                                Toast.makeText(MainActivity.this, "div", 
      Toast.LENGTH_SHORT).show();
                                break;
                        }
                    }
                });
于 2021-05-02T20:23:47.337 回答