Android4.0設計規定的有效可觸摸的UI元素標準是48dp,這是一個用戶手指能準確而且溫馨觸摸的區域。java
以下圖所示,你的UI元素可能小於48dp,圖標僅有32dp,按鈕僅有40dp,可是他們的實際可操做焦點區域最好都應達到48dp的大小。android
假設有兩個View,分別是v1,v2,咱們能夠經過v1的setTouchDelegate(bounds, v2)來委派觸摸事件,其中bounds是一個Rect。v1中,落在這個範圍的TouchEvent都會傳給v2。ide
爲使小的UI區域得到良好的觸摸交互,根據View的特性,目前碰到了兩種狀況:post
狀況1的控件,可直接設置其padding值達到目的,如 android:padding="10dp" .net
狀況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); } } }); }
採起此種方法的兩點注意:rest
若須要恢復該View的觸摸範圍:code
/** * 還原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的方式結合使用。blog
使用post runnable的方式去設置Delegate區域大小的緣由是,如該View是在Activity的OnCreate()或Fragment的OnCreateView()中繪製,此時UI界面還沒有開始繪製,沒法得到正確的座標;事件
若將此法應用在ListView的getView()中繪製每一個ItemView時,則Delegate的設置將部分失效,緣由是ListView的繪製較特殊,可能沒法獲取到部分還未繪製出的View的正確座標,能夠參考:http://cyrilmottier.com/2012/02/16/listview-tips-tricks-5-enlarged-touchable-areas/
參考:http://blog.csdn.net/sgwhp/article/details/10963383