Android中的获取控件矩阵gethitrect方法
来源:互联网 发布:办卡软件 编辑:程序博客网 时间:2024/05/29 05:56
原文地址:http://souly.cn/%E6%8A%80%E6%9C%AF%E5%8D%9A%E6%96%87/2015/07/31/Android%E4%B8%AD%E7%9A%84%E8%8E%B7%E5%8F%96%E6%8E%A7%E4%BB%B6%E7%9F%A9%E9%98%B5getHitRect%E6%96%B9%E6%B3%95/
getHitRect的作用和用法
public void getHitRect(Rect outRect)这个方法用来找到控件占据的矩形区域的矩形坐标。 参数outRect表示控件占据的矩形区域。
测试代码如下,根据代码可以很直观的知道这个函数的用法:
public class MainActivity extends Activity { private TextView textView = null; private Button button = null; Rect Trect = new Rect(); Rect Brect = new Rect(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.tv01); button = (Button) findViewById(R.id.btn); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { textView.getHitRect(Trect); button.getHitRect(Brect); Log.e("TAG", "---------TextView_left-------" + String.valueOf(Trect.left)); Log.e("TAG", "---------TextView_top-------" + String.valueOf(Trect.top)); Log.e("TAG", "---------TextView_right-------" + String.valueOf(Trect.right)); Log.e("TAG", "---------TextView_bottom-------" + String.valueOf(Trect.bottom)); Log.e("TAG", "---------Button_left-------" + String.valueOf(Brect.left)); Log.e("TAG", "---------Button_top-------" + String.valueOf(Brect.top)); Log.e("TAG", "---------Button_right-------" + String.valueOf(Brect.right)); Log.e("TAG", "---------Button_bottom-------" + String.valueOf(Brect.bottom)); } }); }}
查看log如下:
06-17 18:07:55.534: E/hailong(5797): ---------TextView_left-------28106-17 18:07:55.534: E/hailong(5797): ---------TextView_top-------47506-17 18:07:55.534: E/hailong(5797): ---------TextView_right-------43806-17 18:07:55.534: E/hailong(5797): ---------TextView_bottom-------51306-17 18:07:55.534: E/hailong(5797): ---------Button_left-------28106-17 18:07:55.534: E/hailong(5797): ---------Button_top-------51306-17 18:07:55.534: E/hailong(5797): ---------Button_right-------43906-17 18:07:55.534: E/hailong(5797): ---------Button_bottom-------609
这样我们就可以知道控件的顶点坐标了。
可以用类似的方法判断是否点击到该控件上boolean isHit = Trect.contains((int)event.getX(), (int)event.getY());
注意:getHitRect作为获取控件所在的矩阵范围函数,我们平常调用时候如果是在控件的监听器里调用就没事, 但是如果主动的在onCreate 或者 onResume中,拿到的矩阵坐标全是0.因为getHitRect方法不能直接在onCreate中调用 ,原因是该控件还未在这个界面框架中得以测量布局,不知道到底是多少,所以我们要寻找一个时机去做这件事,两个方法:
1.运用该控件执行post(就把下面的那个parent当成你要获取getHitRect的方法)
final View parent = (View) delegate.getParent();parent.post( new Runnable() { // Post in the parent's message queue to make sure the parent // lays out its children before we call getHitRect() public void run() { final Rect r = new Rect(); delegate.getHitRect(r); r.top -= 4; r.bottom += 4; parent.setTouchDelegate( new TouchDelegate( r , delegate)); }});
2.自定义该控件,覆写onDraw,调用getHitRect.
扩大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动态修改其触摸区域,达到扩大点击范围的效果.
这里大致说一下setTouchDelegate的作用:假设有两个View,分别是v1,v2,我们可以通过v1的setTouchDelegate(bounds, v2)来委派触摸事件, 其中bounds是一个Rect。v1中,落在这个范围的TouchEvent都会传给v2。
既然是这样,那我们可以通过设置某个view的parent的touchDelegate来达到扩大这个view触摸范围的目的。 关键是什么时候去执行parent.setTouchDelegate()方法呢?要设置这个委派,必须得知道当前view大小以及它在parent的位置。 而这些数据都是在onLayout才能确定(注:如果不是自定义View,只是在Activity中设置,请将这些操作置于onWindowFocusChanged()方法中)。
代码如下:
/** * 扩大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的方式结合使用。
注意:将此法应用在ListView的getView()中绘制每个ItemView时,则Delegate的设置将部分失效,原因是ListView的绘制较特殊,可能无法获取到部分还未绘制出的View的正确坐标。
- Android中的获取控件矩阵gethitrect方法
- android 关于如何获取控件矩阵 getHitRect
- android 关于如何获取控件矩阵 getHitRect
- Android获取View位置getHitRect、getDrawingRect、getLocalVisibleRect、getGlobalVisibleRect说明
- android中获取NavigationView中的控件方法
- 获取HTML中的父控件方法
- 获取Android中的SHA1方法
- Android自定义控件中获取文字宽高的方法已经drawText中的xy
- Android获取dialog自定义布局中的控件
- android 获取 控件在布局中的位置
- Android获取dialog自定义布局中的控件
- Android获取Dialog自定义布局中的控件
- Android获取dialog自定义布局中的控件
- Android—获取view中的一个控件
- Android获取NavigationView header中的控件
- Android 简化获取控件的方法
- Android 根据坐标获取控件方法
- Android获取控件大小的方法
- mysql数据库表设计和优化
- js的规范写法ES5
- java 常用Math类中的方法总结
- 瓦片自定义导出参数说明
- Python网络爬虫之BeautifulSoup库
- Android中的获取控件矩阵gethitrect方法
- Java JSON 标准 JSR-353 相关
- 常用正则----特殊表达式
- hdu 1010 Tempter of the Bone (dfs + 剪枝)
- C++逆波兰表达式转化实现简单计算器
- POI设置word 2007文本下划线样式及文字底纹
- 数据表示——进制的转换
- js原生alert弹框美化
- 170727 逆向-RousterScan(3)