从其他视图拖动时检测视图上的触摸事件

时间:2012-10-19 18:20:11

标签: android android-view ontouchlistener

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

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

enter image description here

7 个答案:

答案 0 :(得分:61)

您可以使用以下代码来发送您的请求:

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

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

问候。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分: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
}

答案 4 :(得分:0)

尝试使用拖放框架。

答案 5 :(得分:0)

当您在View B上时,请手动调用onTouch

if (viewBRect.contains(x, y)) {
    viewBsonTouch(view, motionEvent);
}

答案 6 :(得分: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;
                        }
                    }
                });