原文地址:http://halohoop.com/2017/06/06/cookies-android-touchdelegate/
开门撞山:
今天我要记录的是TouchDelegate,有很多人应该都不知道还有这个东西,知道的孩子都没你们事了,都散了散了吧,不知道的请往下看。其实也不算什么秘密,只要你仔细的走过神迹一样的事件分发的源码,很容易发现的。
场景:
如下图,有这样一个场景,View a 需要有这么大,比如可以是一个按钮,UI要求显示View a的黑框部分,但是为了更好的用户体验,我们一般会增大其触控范围,比如点击绿框中都能够触发a的事件,咋做?(说好的不卖关子的呢?)
Don’t do:
- 增加a的Padding?
- 后期如果修改bgColor,那么不好了,绿色框内全变色。
- 套多一层透明的FrameLayout?
- 增加布局复杂度,我TM一脚飞死你。
- 自定义view限制绘制区域?
- 写完了?你很棒!但是你可以收拾包袱走人了。
What should do (How to use TouchDelegate):
要学会站在巨人的肩膀,要知道,“你遇到的,巨人也会遇到”,巨人给我们留下了TouchDelegate
直接上菜:
注意方法ViewGroup.setTouchDelegate(Rect,View)
以下代码出自我一个自定义View—UsoppBubble.java
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
float largedSize = (bottom - top) * mTouchAreaLargerRatio;//乘以放大倍数
int deltaY = (int) (largedSize - (bottom - top));
int deltaX = largedSize > (right - left) ? (int) (largedSize - (right - left)) : 0;
ViewGroup vg = (ViewGroup) getParent();
Rect rect = new Rect(left - deltaX, top - deltaY, right + deltaX, bottom + deltaY);
//构建出来的Rect对象就相当于绿色框框,而this就是这个view的实例。
vg.setTouchDelegate(new TouchDelegate(rect, this));
}
}
相信上述代码是极度容易的,ViewGroup.setTouchDelegate(Rect,View)接受两个参数:
- 可触控区域。
- 谁(哪个子view)需要用这个可触控区域。
实际应用场景
- QQ消息气泡可触控区域
- 当然我也模仿qq做了一个自己的消息气泡版本
- 小米贴边悬浮球点击唤醒
- 锤子的闪念胶囊贴边点击唤醒
总结
- View.setTouchDelegate(Rect,View),这句还不够吗?还要我怎样?
- 你遇到的,巨人也会遇到,如果换位思考一下,你就是“巨人”,那么子View获取到的触摸事件是从ViewGroup分发下来的,那么如果在分发之前加一些条件判断,比如区域什么的,那么TouchDelegate这玩意儿是不是就出来了呢?
- Stay hungry stay foolish!
仅作知识点记录,如有疏漏,全(欢)都(迎)怪(指)你(正)。
确保这文章被看完了,我在上面留了一个无伤大雅的bug,不知道有人发现没有,那就是:
setTouchDelegate其实是View的方法。而ViewGroup : View,无伤大雅。
顺便说一下,科学上网之后浏览本站文章可以评论。