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 TouchDelegate源码解析

android.view.TouchDelegate是用来扩大View的触摸点击区域的。用法很简单,套路是: 比如 mButton = new CheckBox(getContext());Rec...
  • fancylovejava
  • fancylovejava
  • 2015年10月10日 00:53
  • 2058

TouchDelegate

/**  * Helper class to handle situations where you want a view to have a larger touch area than its ...
  • hqdoremi
  • hqdoremi
  • 2013年07月24日 11:17
  • 532

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

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

Android中TouchDelegate的用法浅析

一般TouchDelegate是在View类中的。 View类中出现TouchDelegate的地方如下: public class View implements Drawable.Callback...
  • oldmtn
  • oldmtn
  • 2013年07月04日 17:33
  • 1841

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

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

android之view的TouchDelegate

ouchDelegate是一个工具类,其目的是让一个view在一个特定的位置拥有比自己实际的触摸区域更大的可触摸的区域.触摸区域被更改的view被称作"delegate view".这个工具类应该被"...
  • Green_shing
  • Green_shing
  • 2015年06月18日 18:44
  • 1349

Android TouchDelegate

TouchDelegate是个挺有意思的小玩意,它可以帮助我们让某个控件处理比它实际占用空间更大的触摸消息 Android TouchDelegate...
  • afanyusong
  • afanyusong
  • 2015年11月03日 09:36
  • 108

Android笔记之利用TouchDelegate扩大View点击区域

有时候美工提供给我们的图标是很小的,但却要在如此小的图标上附加点击事件,如果不做处理,用户在使用的时候是很难点中的。当然,我们可以通过布局做调整处理,但是往往是布局变得更复杂。现在我们通过TouchD...
  • quwei3930921
  • quwei3930921
  • 2016年09月06日 10:58
  • 524

利用TouchDelegate提升用户体验

最近在维护公司的老项目,客户反馈了一个问题: 点赞的红色小桃心有时点击之后没有响应。嗯哼,既然客户说有这个问题,那么就需要确认一下。 从豌豆荚上下载了一个最新版本,安装后跳转到详情页面,然后点赞。...
  • lfdfhl
  • lfdfhl
  • 2016年09月01日 17:06
  • 5226

clipChild、clipToPadding和TouchDelegate

android:clipChildren的意思:是否限制子View在其范围内,我们将其值设置为false后那么当子控件的高度高于父控件时也会完全显示,而不会被压缩 注意android:cli...
  • u011028777
  • u011028777
  • 2017年01月14日 12:29
  • 172
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:TouchDelegate分析
举报原因:
原因补充:

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