用 TouchDelegate 扩大子 View 的点击区域

来源:互联网 发布:魔兽3.35数据库 编辑:程序博客网 时间:2024/04/28 13:45

原文出处:http://developer.android.com/training/gestures/viewgroup.html#delegate

点击区域的大小会影响到用户体验,除了扩大可点击 View 的 padding 之外,今天偶遇另一种方法,在父 View 级别增大子 View 的点击区域。

gist 被墙,csdn code 402,暂且当做博客记录,以备不时之需。

安卓提供了 TouchDelegate 类来让父 View 扩大子 View 的可点击区域。使用场景是,子 View 必须很小,但是又要有较大的点击区域。当然,如果你愿意,也可以用该类来缩小子 View 的点击区域。

下面的例子中,ImageButton 是“代理 View”(即,自己不争气、需要靠爹 View 来帮助扩大点击区域的子 View)。layout 如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:id="@+id/parent_layout"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity" >     <ImageButton android:id="@+id/button"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:background="@null"          android:src="@drawable/icon" /></RelativeLayout>

下面的代码片段作用如下:

  • 获取父 View ,然后在 UI 线程 post 一个 Runnable,保证父 View 在摆放各个子 View 之前调用 getHitRect() 方法。该方法得到子 View 的点击区域;
  • 找到可点击的 ImageButton,调用 getHitRect() 方法获取其可点击区域的边界;
  • 扩大 ImageButton 的可点击区域;
  • 实例化 TouchDelegate,在其构造方法中传入扩大后的可点击区域和 ImageButton。在父 View 中设置 TouchDelegate,以便父 View 代理的区域内的点击事件能传给 ImageButton;

在被代理的区域内,父 View 会获取所有的 touch 事件,然后传递给子 View 处理。

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // Get the parent view        View parentView = findViewById(R.id.parent_layout);        parentView.post(new Runnable() {            // Post in the parent's message queue to make sure the parent            // lays out its children before you call getHitRect()            @Override            public void run() {                // The bounds for the delegate view (an ImageButton                // in this example)                Rect delegateArea = new Rect();                ImageButton myButton = (ImageButton) findViewById(R.id.button);                myButton.setEnabled(true);                myButton.setOnClickListener(new View.OnClickListener() {                    @Override                    public void onClick(View view) {                        Toast.makeText(MainActivity.this,                                 "Touch occurred within ImageButton touch region.",                                 Toast.LENGTH_SHORT).show();                    }                });                // The hit rectangle for the ImageButton                myButton.getHitRect(delegateArea);                // Extend the touch area of the ImageButton beyond its bounds                // on the right and bottom.                delegateArea.right += 100;                delegateArea.bottom += 100;                // Instantiate a TouchDelegate.                // "delegateArea" is the bounds in local coordinates of                 // the containing view to be mapped to the delegate view.                // "myButton" is the child view that should receive motion                // events.                TouchDelegate touchDelegate = new TouchDelegate(delegateArea,                         myButton);                // Sets the TouchDelegate on the parent view, such that touches                 // within the touch delegate bounds are routed to the child.                if (View.class.isInstance(myButton.getParent())) {                    ((View) myButton.getParent()).setTouchDelegate(touchDelegate);                }            }        });    }}
1 0
原创粉丝点击