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

by sgwhp,转载请注明。

还不知道TouchDelegate这个东西的可以先看一下API,这里大致说一下它的作用:假设有两个View,分别是v1,v2,我们可以通过v1的setTouchDelegate(bounds, v2)来委派触摸事件,其中bounds是一个Rect。v1中,落在这个范围的TouchEvent都会传给v2。

既然是这样,那我们可以通过设置某个view的parent的touchDelegate来达到扩大这个view触摸范围的目的。关键是什么时候去执行parent.setTouchDelegate()方法呢?要设置这个委派,必须得知道当前view大小以及它在parent的位置。而这些数据都是在onLayout才能确定(注:如果不是自定义View,只是在Activity中设置,请将这些操作置于onWindowFocusChanged()方法中)。至此,实现的思路已经很清晰了,我们通过自定义一个Button来检验一下,下面开始上代码:

为了方便在xml中使用我们自定义的View,并且可以自定义扩大的触摸范围,我们再自定义一个attrs,res/values/attrs.xml:

Button实现:

publicclassLargeTouchableAreasButtonextendsButton {

privatefinalintTOUCH_ADDITION =0;

privateintmTouchAdditionBottom =0;

privateintmTouchAdditionLeft =0;

privateintmTouchAdditionRight =0;

privateintmTouchAdditionTop =0;

privateintmPreviousLeft = -1;

privateintmPreviousRight = -1;

privateintmPreviousBottom = -1;

privateintmPreviousTop = -1;

publicLargeTouchableAreasButton(Context context) {

super(context);

}

publicLargeTouchableAreasButton(Context context, AttributeSet attrs) {

super(context, attrs);

init(context, attrs);

}

publicLargeTouchableAreasButton(Context context, AttributeSet attrs,

intdefStyle) {

super(context, attrs, defStyle);

init(context, attrs);

}

privatevoidinit(Context context, AttributeSet attrs) {

TypedArray a = context.obtainStyledAttributes(attrs,

R.styleable.LargeTouchableAreaView);

intaddition = (int) a.getDimension(

R.styleable.LargeTouchableAreaView_addition, TOUCH_ADDITION);

mTouchAdditionBottom = addition;

mTouchAdditionLeft = addition;

mTouchAdditionRight = addition;

mTouchAdditionTop = addition;

mTouchAdditionBottom = (int) a.getDimension(

R.styleable.LargeTouchableAreaView_additionBottom,

mTouchAdditionBottom);

mTouchAdditionLeft = (int) a.getDimension(

R.styleable.LargeTouchableAreaView_additionLeft,

mTouchAdditionLeft);

mTouchAdditionRight = (int) a.getDimension(

R.styleable.LargeTouchableAreaView_additionRight,

mTouchAdditionRight);

mTouchAdditionTop = (int) a.getDimension(

R.styleable.LargeTouchableAreaView_additionTop,

mTouchAdditionTop);

a.recycle();

}

@Override

protectedvoidonLayout(booleanchanged,intleft,inttop,intright,

intbottom) {

super.onLayout(changed, left, top, right, bottom);

if(left != mPreviousLeft || top != mPreviousTop

|| right != mPreviousRight || bottom != mPreviousBottom) {

mPreviousLeft = left;

mPreviousTop = top;

mPreviousRight = right;

mPreviousBottom = bottom;

finalView parent = (View)this.getParent();

parent.setTouchDelegate(newTouchDelegate(newRect(left

- mTouchAdditionLeft, top - mTouchAdditionTop, right

+ mTouchAdditionRight, bottom + mTouchAdditionBottom), this));

}

}

}

然后在具体要使用到这个Button的xml中加上以下代码:

xmlns:lta="http://schemas.android.com/apk/res/com.xxx.xxx"

其中"lta"这个名字可以随便取,最后的是你的app包名。

最后在这个Button中定义希望增大的尺寸:

android:layout_width="wrap_content"

android:layout_height="wrap_content"

lta:addition="30dp"/>

大功告成。

但这个自定义的View并不是完美的,还存在以下问题:

1、必须保证parent足够大,如果自定义的范围超出parent的大小,则超出的那部分无效。

2、一个parent只能设置一个触摸委派,设置多个时,只有最后设置的child有效。如果希望一个view能设置多个委派,需要再自定义parent,具体方法可参考:http://cyrilmottier.com/2012/02/16/listview-tips-tricks-5-enlarged-touchable-areas/

总而言之,要触发委派,必须保证parent接收到了触摸事件,并且落在了你定义的范围内。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值