Android 扩大view点击范围
Android4.0设计规定的有效可触摸的UI元素标准是48dp,转化为一个物理尺寸约为9毫米。7~10毫米,这是一个用户手指能准确并且舒适触摸的区域。
如下图所示,你的UI元素可能小于48dp,图标仅有32dp,按钮仅有40dp,但是他们的实际可操作焦点区域最好都应达到48dp的大小。

为使小的UI区域获得良好的触摸交互,根据View的特性,目前碰到了两种情况:
1.如ImageView,设置其padding值,可触摸区域将向外扩展;
2.如Button,设置其padding值,可触摸区域不变,其内内容显示区域向内压缩;
情况1的控件,可直接设置其padding值达到目的,如 android:padding="10dp"
情况2的控件,可使用TouchDelegate动态修改其触摸区域,达到扩大点击范围的效果
- /**
- * 扩大View的触摸和点击响应范围,最大不超过其父View范围
- *
- * @param view
- * @param top
- * @param bottom
- * @param left
- * @param right
- */
- public static void expandViewTouchDelegate(final View view, final int top,
- final int bottom, final int left, final int right) {
- ((View) view.getParent()).post(new Runnable() {
- @Override
- public void run() {
- Rect bounds = new Rect();
- view.setEnabled(true);
- view.getHitRect(bounds);
- bounds.top -= top;
- bounds.bottom += bottom;
- bounds.left -= left;
- bounds.right += right;
- TouchDelegate touchDelegate = new TouchDelegate(bounds, view);
- if (View.class.isInstance(view.getParent())) {
- ((View) view.getParent()).setTouchDelegate(touchDelegate);
- }
- }
- });
- }
采取此种方法的两点注意:
1、若View的自定义触摸范围超出Parent的大小,则超出的那部分无效。
2、一个Parent只能设置一个View的TouchDelegate,设置多个时只有最后设置的生效。
若需要恢复该View的触摸范围:
- /**
- * 还原View的触摸和点击响应范围,最小不小于View自身范围
- *
- * @param view
- */
- public static void restoreViewTouchDelegate(final View view) {
- ((View) view.getParent()).post(new Runnable() {
- @Override
- public void run() {
- Rect bounds = new Rect();
- bounds.setEmpty();
- TouchDelegate touchDelegate = new TouchDelegate(bounds, view);
- if (View.class.isInstance(view.getParent())) {
- ((View) view.getParent()).setTouchDelegate(touchDelegate);
- }
- }
- });
- }
使用TouchDelegate扩大View的触摸响应范围是一种比较灵活的方法,有时可与设置padding的方式结合使用。
更新
======
后期实际开发中发现,使用post runnable的方式去设置Delegate区域大小的原因是,如该View师在Activity的OnCreate()或Fragment的OnCreateView()中绘制,此时UI界面尚未开始绘制,无法获得正确的坐标;
若将此法应用在ListView的getView()中绘制每个ItemView时,则Delegate的设置将部分失效,原因是ListView的绘制较特殊,可能无法获取到部分还未绘制出的View的正确坐标。解决方案具体可参考以下参考阅读所列。
参考阅读:通过自定义View的方式,及某些其他情况的处理:
1.《Android使用TouchDelegate增加View的触摸范围》 http://blog.csdn.net/sgwhp/article/details/10963383
2.《ListView Tips & Tricks #5: Enlarged Touchable Areas》 http://cyrilmottier.com/2012/02/16/listview-tips-tricks-5-enlarged-touchable-areas/
3.《Extend touchable areas #Android》 https://plus.google.com/u/0/+JulienDodokal/posts/8zoV3RQvReS
Android 扩大view点击范围的更多相关文章
- android中View点击和触摸事件的处理
android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解. 一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN-& ...
- Android 自定义View——自定义点击事件
每个人手机上都有通讯录,这是毫无疑问的,我们通讯录上有一个控件,在通讯录的最左边有一列从”#”到”Z”的字母,我们通过滑动或点击指定的字母来确定联系人的位置,进而找到联系人.我们这一节就通过开发这个控 ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- android中ListView点击和里边按钮点击不能同时生效问题解决
今天遇到一个问题:android中ListView点击和里边button点击不能同时生效问题解决. 原因是: listView 在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得 ...
- android自定义View之NotePad出鞘记
现在我们的手机上基本都会有一个记事本,用起来倒也还算方便,记事本这种东东,如果我想要自己实现,该怎么做呢?今天我们就通过自定义View的方式来自定义一个记事本.OK,废话不多说,先来看看效果图. 整个 ...
- android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索
我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体 ...
- Android 自定义View (二) 进阶
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自定义View之旅,前面已经介绍过一个自定义View的基础的例 ...
- Android 自定义View (一)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...
- Android自定义View研究--View中的原点坐标和XML中布局自定义View时View触摸原点问题
这里只做个汇总~.~独一无二 文章出处:http://blog.csdn.net/djy1992/article/details/9715047 Android自定义View研究--View中的原点坐 ...
随机推荐
- [sql]mysql指引(整理中...)-对db的分类
参考 db存储及分层 一个db一个文件夹. 一张表两个文件frm是存表结构的,ibd是存数据的 连接层: sock ip sql层: 存储层: 2018年4月1日 20:53:54小结: 时间太久,抓 ...
- SQL作业
USE [test] GO /****** Object: StoredProcedure [dbo].[wangchuang] Script Date: 2016/8/25 14:09:24 *** ...
- 关于在node项目使用ioredis遇到的几个坑
1,在ioredis中使用redis命令的方法的时候,如果有2个以上的参数,必须使用then方法来接收返回的结果,比如: redis.hget('key','field').then(function ...
- DataTable的初始化与事件注册
TypeScript代码: let tabledata = data as any[]; if (this.dataTable) { this.dataTable.clear(); this.data ...
- 使用Windows 10专业版 进行VS2017开发 遇到 HTTP Error 400. The request hostname is invalid
使用IIS Express 支持非localhost访问 只要使用域名或者本机IP地址都无法进行 iisexpress 调试 公网ip,还是127.0.0.1都出现上面那个错误 主要是新的系统环境 ...
- Pycharm 2017.1 激活服务器
最近发现pycharm激活异常困难 原来的激活码 都不能用了 so 根据网上 教程 自己建了激活服务器 尝试可用服务器 20170504 测试发现 给需要域名 http://www.05nb.com: ...
- 【设计模式】装饰器模式与Java Servlet、Spring Session在其中的使用
简述 装饰器模式,可以通过装饰器类,通过依赖原实现的方式(不使用继承),达到扩展原实现的目的.UML图如下: ServletRequestWrapper于其中的使用 ServletRequestWra ...
- 【内核】linux内核启动流程详细分析
Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...
- Lintcode: Kth Largest Element 解题报告
Kth Largest Element Find K-th largest element in an array. Note You can swap elements in the array E ...
- 使用 Trace 将日志输入到文件中
工具没有好坏,只有适不适用.由于项目中用 Log4Net 过重,所以使用 Trace 代替了 Log4Net 输入一些简单的日志信息: 自定义监听文件 using System; using Syst ...