TouchDelegate分析

原创 2013年12月02日 12:22:56

在View.java中,使用TouchDelegate的代码很少,它的实现机制也非常的简单。先看看它在View.java中的代码:

    /**
     * The delegate to handle touch events that are physically in this view
     * but should be handled by another view.
     */
    private TouchDelegate mTouchDelegate = null;//说明了这个类对象的应用意义:把此View的触摸事件交由另外的View处理

    public boolean onTouchEvent(MotionEvent event) {
    ...
        if (mTouchDelegate != null) {
            if (mTouchDelegate.onTouchEvent(event)) {//如果设置了代理,那么事件交由代理处理,并且如果代理成功处理了事件,那么事件结束
                return true;
            }
        }

    public void setTouchDelegate(TouchDelegate delegate) {
        mTouchDelegate = delegate;
    }


    public TouchDelegate getTouchDelegate() {
        return mTouchDelegate;
    }

下面我们再来看看TouchDelegate.java源码:

/**
 * Helper class to handle situations where you want a view to have a larger touch area than its
 * actual view bounds. The view whose touch area is changed is called the delegate view. This
 * class should be used by an ancestor of the delegate. To use a TouchDelegate, first create an
 * instance that specifies the bounds that should be mapped to the delegate and the delegate
 * view itself.
 * <p>
 * The ancestor should then forward all of its touch events received in its
 * {@link android.view.View#onTouchEvent(MotionEvent)} to {@link #onTouchEvent(MotionEvent)}.
 * </p>
 */

//上面这段话注释在类的开头,它交代了TouchDelegate的使用意义——当我们希望View的触摸区域大于它实际的大小时可以使用这个代理实现和使用方法——它作为基类(即我们可以继承它写自己的代理),创建一个实例,这个实例需要指定一个区域和一个代理视图,代理视图可以是它本身。
//接下来看看它的构造函数,基本上就了解了如何使用这个辅助类。
    public TouchDelegate(Rect bounds, View delegateView) {
        mBounds = bounds;

        mSlop = ViewConfiguration.get(delegateView.getContext()).getScaledTouchSlop();
        mSlopBounds = new Rect(bounds);
        mSlopBounds.inset(-mSlop, -mSlop);
        mDelegateView = delegateView;
    }

//最重要的是onTouchEvent()这个函数,看看它是如何把触摸事件交给代理去处理的。首先说明一点,TouchDelegate是一个基类,我们可以继承它并按照自己的方式去实现代理
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int)event.getX();
        int y = (int)event.getY();
        boolean sendToDelegate = false;
        boolean hit = true;
        boolean handled = false;

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Rect bounds = mBounds;

            if (bounds.contains(x, y)) {//如果触摸点坐标在我们指定的代理的区域内,那么事件交给代理View处理
                mDelegateTargeted = true;
                sendToDelegate = true;
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_MOVE:
            sendToDelegate = mDelegateTargeted;
            if (sendToDelegate) {
                Rect slopBounds = mSlopBounds;
                if (!slopBounds.contains(x, y)) {
                    hit = false;
                }
            }
            break;
        case MotionEvent.ACTION_CANCEL:
            sendToDelegate = mDelegateTargeted;
            mDelegateTargeted = false;
            break;
        }
        if (sendToDelegate) {
            final View delegateView = mDelegateView;
            
            if (hit) {
                // Offset event coordinates to be inside the target view
                event.setLocation(delegateView.getWidth() / 2, delegateView.getHeight() / 2);
            } else {
                // Offset event coordinates to be outside the target view (in case it does
                // something like tracking pressed state)
                int slop = mSlop;
                event.setLocation(-(slop * 2), -(slop * 2));
            }
            handled = delegateView.dispatchTouchEvent(event);//事件交由代理View去处理
        }
        return handled;
    }

通过上面这些源码可知,TouchDelegate有两种应用:

1.仅是拓宽(或缩小)触摸区域,把DelegateView设置为它本身,Bounds设置的区域就是代理点击的区域。这里有个疑惑,当点击区域在View本身的范围内时,ViewGroup才会把触摸事件分配给它。而在Bounds区域内,View获取不到触摸事件,又如何把触摸事件交给代理呢?

2.把触摸事件交给另外的View——DelegateView处理


相关文章推荐

Android事件分发08——TouchDelegate的使用的一个示例与问题分析

Android事件分发08TouchDelegate的使用的一个示例与问题分析 一问题分析 1 如何实现 2 相交部分的坐标处理 二实现 mForginViewsetT...

android之view的TouchDelegate

ouchDelegate是一个工具类,其目的是让一个view在一个特定的位置拥有比自己实际的触摸区域更大的可触摸的区域.触摸区域被更改的view被称作"delegate view".这个工具类应该被"...

android学习之-----使用TouchDelegate增大触摸面积

需求:   有时候由于界面上图标过小 ,导致点击触摸的区域太小不好操作,或者有时候会发生误操作。 解决办法:   如果是图片设置src属性,设置padding  ,或者外层嵌套一...

用 TouchDelegate 扩大子 View 的点击区域

点击区域的大小会影响到用户体验,除了扩大可点击 View 的 padding 之外,今天偶遇另一种方法,在父 View 级别增大子 View 的点击区域。gist 被墙,csdn code 402,暂...
  • zhaizu
  • zhaizu
  • 2015年11月19日 17:46
  • 1201

Android使用TouchDelegate增加View的触摸范围

by sgwhp,转载请注明。 还不知道TouchDelegate这个东西的可以先看一下API,这里大致说一下它的作用:假设有两个View,分别是v1,v2,我们可以通过v1的setTo...
  • sgwhp
  • sgwhp
  • 2013年09月03日 11:26
  • 10447

使用android.view.TouchDelegate扩大View的触摸点击区域

Android4.0规定的有效可触摸的UI元素标准是48dp,转化为一个物理尺寸,约为9毫米。建议的目标大小为7~10毫米,这一点与iPhone一致,这是一个用户手指能准确并且舒适触摸的区域。如果所示...
  • tongcpp
  • tongcpp
  • 2014年04月11日 16:30
  • 19695

Android事件分发07——TouchDelegate的使用与解析

Android事件分发07TouchDelegate的使用与解析 一TouchDelegate的简单使用 1 图示 2 activity_touch_delegate_demoxml 2 TouchD...

使用TouchDelegate增大控件的触摸范围

转载请注明出处: 在很多Android应用有时候为了美观,有时候可能受限于屏幕大小,有些控件不能显示太大。但是控件太小,又不方便用户点击,影响体验。有没有办法可以在不调整控件大小的情况增大控件接收触摸...

使用 TouchDelegate 扩大控件的点击范围

当我们的控件太小,导致我们无法准确的点击,这个时候我们可以在这个控件外面再加一层布局,但是这样对性能不太好。其实,我们可以使用 TouchDelegate 扩大我们的点击范围。 下面是例子,我们...

使用android.view.TouchDelegate扩大View的触摸点击区域

Android4.0规定的有效可触摸的UI元素标准是48dp,转化为一个物理尺寸,约为9毫米。建议的目标大小为7~10毫米,这一点与iPhone一致,这是一个用户手指能准确并且舒适触摸的区域。如果所示...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:TouchDelegate分析
举报原因:
原因补充:

(最多只允许输入30个字)