Android提供了一个TouchDelegate
类去让父类扩展它的子view的触摸区域。当子view很小但需要大的触摸区域的时候,这个类大有用处。如果你想要的话,你也能用这个类去缩小子view的触摸区域。
在下面的例子中,有一个作为例子的ImageButton
(也就是说父类会扩展这个子view的触摸区域)
、
在下面的例子中,有一个作为例子的ImageButton
(也就是说父类会扩展这个子view的触摸区域)
<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并post一个
Runnable
到UI线程。这会确保父类在调用getHitRect()
)方法前先勾画出他的子类。getHitRect()
)方法的作用是在父类的坐标系中获取子view的hit rectangle(触摸区域)。 - 找到
ImageButton
子view并调用getHitRect()
)去获取子类触摸区域范围。 - 扩展
ImageButton
的hit rectangle范围。 - 初始化
TouchDelegate
对象,参数是扩展后的hit rectangle和ImageButton
子view。 - 在父view中设置
TouchDelegate
,这样在这个触摸范围内的touch event都会传给ImageButton
在ImageButton
子view的触摸范围容量内,父view会接收所有的touch events,如果touch event发生在子类的hit rectangle内,父类会将touch event传给子类做处理。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取父view
View parentView = findViewById(R.id.parent_layout);
parentView.post(new Runnable() {
// post到父类的消息队列中,确保在调用getHitRect()前勾画出子类
@Override
public void run() {
// 实例view的区域范围(ImageButton)
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();
}
});
// ImageButton的hit rectangle
myButton.getHitRect(delegateArea);
// 在ImageButton边框的右边和底边扩展触摸区域
delegateArea.right += 100;
delegateArea.bottom += 100;
// 初始化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);
}
}
});
}
}