如何子和父视图组触摸事件之间变化 [英] How to vary between child and parent view group touch events

查看:128
本文介绍了如何子和父视图组触摸事件之间变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定发布这个问题,并响应回答<一href="http://stackoverflow.com/questions/28179769/how-to-handle-click-in-the-child-views-and-touch-in-the-parent-viewgroups#comment49963437_28180281">to此评论这个问题:
 <一href="http://stackoverflow.com/questions/28179769/how-to-handle-click-in-the-child-views-and-touch-in-the-parent-viewgroups">How处理单击子视图,和触摸父ViewGroups?。

我会在这里粘贴注释:

  

假设我想重写触摸事件仅用于处理一些   孩子们,我能做到这一点的功能里面有它的工作?   我的意思是,有些孩子会像往常一样工作,而对于一些人来说,   家长认为将决定他们是否会得到触摸事件与否。

所以,问题是,我怎么prevent父的onTouchEvent()从覆盖一些子元素的onTouchEvent(),而不是别人?

解决方案
  1. onTouchEvents()的嵌套视图组可以通过布尔管理 <一个href="http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)">onInterceptTouchEvent.

为默认值 OnInterceptTouchEvent 是假的。

父的的onTouchEvent 之前孩子的欢迎。如果 OnInterceptTouchEvent 返回false,它发出的运动赛事环比下跌给孩子的的onTouchEvent 处理程序。如果返回true母公司将处理触摸事件。

但是可能有情况下,当我们需要一些子元素来管理的onTouchEvent 和一些由父视图(或者可能是父母的父母)进行管理。

这可以一​​种以上的方式进行管理。

<醇开始=2>
  • 子元素可以保护的一种方式父 OnInterceptTouchEvent 是通过执行<一个href="http://developer.android.com/reference/android/view/ViewGroup.html#requestDisallowInterceptTouchEvent(boolean)">requestDisallowInterceptTouchEvent.
  •   

    公共无效requestDisallowInterceptTouchEvent(布尔   disallowIntercept)

    这prevents任何从管理的onTouchEvent 此元素,如果该元素具有事件处理功能。

    家长意见 <醇开始=3>
  • 如果 OnInterceptTouchEvent 是假的,子元素的的onTouchEvent 进行评估。如果您有子元素处理各种触摸事件中的方法,即禁止任何相关的事件处理程序的的onTouchEvent返回父。
  • 这答案:
    http://stackoverflow.com/a/13540006/3956566 给出了如何触摸事件的传播经过了良好的可视化:
     母公司 - &GT;孩子|父母 - &GT;孩子|父母 - &GT;孩子的意见。

    <醇开始=4>
  • 在另一种方式是从 OnInterceptTouchEvent 父。
  • 返回不同的值

    这个例子取自中的ViewGroup 管理触摸事件,并演示了如何截取孩子的的onTouchEvent 当用户滚动。

    4A。

      @覆盖
    公共布尔onInterceptTouchEvent(MotionEvent EV){
        / *
         *此方法只决定了我们是否要拦截的议案。
         *如果我们返回true,的onTouchEvent将被调用,我们做实际的
         *滚动出现。
         * /
    
    
        最终诠释行动= MotionEventCompat.getActionMasked(EV);
    
        //总是处理触摸手势是完整的情况。
        如果(行动== MotionEvent.ACTION_CANCEL ||行动== MotionEvent.ACTION_UP){
            //释放卷轴。
            mIsScrolling = FALSE;
            返回false; //不要拦截触摸事件,让孩子处理它
        }
    
        开关(动作){
            案例MotionEvent.ACTION_MOVE:{
                如果(mIsScrolling){
                    //目前,我们正在滚动,所以是的,拦截
                    //触摸事件!
                    返回true;
                }
    
                //如果用户已经拖了她的手指比水平更
                //触摸坡,开始滚动
    
                //作为练习留给读者
                最终诠释xDiff = calculateDistanceX(EV);
    
                //触摸污水应使用ViewConfiguration计算
                //常量。
                如果(xDiff&GT; mTouchSlop){
                    //开始滚动!
                    mIsScrolling = TRUE;
                    返回true;
                }
                打破;
            }
            ...
        }
    
        //在一般情况下,我们不希望拦截触摸事件。它们应该是
        //通过子视图处理。
        返回false;
    }
     

    编辑:要回答的意见
    。 这是展示如何创建一个在你的元素矩形的参数相同的链接一些code:
    图4b。

      //命中矩形的的ImageButton
    myButton.getHitRect(delegateArea);
    
    //扩展的ImageButton的触摸区域超出其范围
    //在右侧和底部。
    delegateArea.right + = 100;
    delegateArea.bottom + = 100;
    
    //实例化一个TouchDelegate。
    //delegateArea是在本地坐标的边界
    //含视图要映射到委托视图。
    //则myButton是应该得到运动子视图
    //事件。
    TouchDelegate touchDelegate =新TouchDelegate(delegateArea,则myButton);
    
    //设置TouchDelegate父视图,使得触摸
    //触摸内委托范围被路由到孩子。
    如果(View.class.isInstance(myButton.getParent())){
        ((查看)myButton.getParent())setTouchDelegate(touchDelegate)。
    }
     

    I decided to post this question and answer in response to this comment to this question:
    How to handle click in the child Views, and touch in the parent ViewGroups?.

    I will paste the comment here:

    Suppose I want to override the touch events only for handling some of the children, what can I do inside this function to have it working ? I mean, for some children it would work as usual, and for some, the parent-view will decide if they will get the touch events or not.

    So the question is, how do I prevent the parent onTouchEvent() from overriding some child elements' onTouchEvent() and not others?

    解决方案

    1. The onTouchEvents() for nested view groups can be managed by the boolean onInterceptTouchEvent.

    The default value for the OnInterceptTouchEvent is false.

    The parent's onTouchEvent is received before the child's. If the OnInterceptTouchEvent returns false, it sends the motion event down the chain to the child's OnTouchEvent handler. If it returns true the parent's will handle the touch event.

    However there may be instances when we want some child elements to manage OnTouchEvents and some to be managed by the parent view (or possibly the parent of the parent).

    This can be managed in more than one way.

    1. One way a child element can be protected from the parent's OnInterceptTouchEvent is by implementing the requestDisallowInterceptTouchEvent.

    public void requestDisallowInterceptTouchEvent (boolean disallowIntercept)

    This prevents any of the parent views from managing the OnTouchEvent for this element, if the element has event handlers enabled.

    1. If the OnInterceptTouchEvent is false, the child element's OnTouchEvent will be evaluated. If you have a methods within the child elements handling the various touch events, any related event handlers that are disabled will return the OnTouchEvent to the parent.

    This answer:
    http://stackoverflow.com/a/13540006/3956566 gives a good visualisation of how the propagation of touch events passes through:
    parent -> child|parent -> child|parent -> child views.

    1. Another way is returning varying values from the OnInterceptTouchEvent for the parent.

    This example taken from Managing Touch Events in a ViewGroup and demonstrates how to intercept the child's OnTouchEvent when the user is scrolling.

    4a.

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        /*
         * This method JUST determines whether we want to intercept the motion.
         * If we return true, onTouchEvent will be called and we do the actual
         * scrolling there.
         */
    
    
        final int action = MotionEventCompat.getActionMasked(ev);
    
        // Always handle the case of the touch gesture being complete.
        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            // Release the scroll.
            mIsScrolling = false;
            return false; // Do not intercept touch event, let the child handle it
        }
    
        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                if (mIsScrolling) {
                    // We're currently scrolling, so yes, intercept the 
                    // touch event!
                    return true;
                }
    
                // If the user has dragged her finger horizontally more than 
                // the touch slop, start the scroll
    
                // left as an exercise for the reader
                final int xDiff = calculateDistanceX(ev); 
    
                // Touch slop should be calculated using ViewConfiguration 
                // constants.
                if (xDiff > mTouchSlop) { 
                    // Start scrolling!
                    mIsScrolling = true;
                    return true;
                }
                break;
            }
            ...
        }
    
        // In general, we don't want to intercept touch events. They should be 
        // handled by the child view.
        return false;
    }
    

    Edit: To answer comments.
    This is some code from the same link showing how to create the parameters of the rectangle around your element:
    4b.

    // The hit rectangle for the ImageButton
    myButton.getHitRect(delegateArea);
    
    // Extend the touch area of the ImageButton beyond its bounds
    // on the right and bottom.
    delegateArea.right += 100;
    delegateArea.bottom += 100;
    
    // Instantiate a TouchDelegate.
    // "delegateArea" is the bounds in local coordinates of 
    // the containing view to be mapped to the delegate view.
    // "myButton" is the child view that should receive motion
    // events.
    TouchDelegate touchDelegate = new TouchDelegate(delegateArea, myButton);
    
    // Sets the TouchDelegate on the parent view, such that touches 
    // within the touch delegate bounds are routed to the child.
    if (View.class.isInstance(myButton.getParent())) {
        ((View) myButton.getParent()).setTouchDelegate(touchDelegate);
    }
    

    这篇关于如何子和父视图组触摸事件之间变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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