Android使用TouchDelegate增加View的觸摸范圍
本文為大家分享了Android使用TouchDelegate增加View觸摸范圍的方法,供大家參考,具體內容如下
還不知道TouchDelegate這個東西的可以先看一下API,這里大致說一下它的作用:假設有兩個View,分別是v1,v2,我們可以通過v1的setTouchDelegate(bounds, v2)來委派觸摸事件,其中bounds是一個Rect。v1中,落在這個范圍的TouchEvent都會傳給v2。
既然是這樣,那我們可以通過設置某個view的parent的touchDelegate來達到擴大這個view觸摸范圍的目的。關鍵是什么時候去執(zhí)行parent.setTouchDelegate()方法呢?要設置這個委派,必須得知道當前view大小以及它在parent的位置。而這些數據都是在onLayout才能確定(注:如果不是自定義View,只是在Activity中設置,請將這些操作置于onWindowFocusChanged()方法中)。至此,實現的思路已經很清晰了,我們通過自定義一個Button來檢驗一下,下面開始上代碼:
為了方便在xml中使用我們自定義的View,并且可以自定義擴大的觸摸范圍,我們再自定義一個attrs,res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LargeTouchableAreaView">
<attr name="addition" format="dimension" />
<attr name="additionBottom" format="dimension" />
<attr name="additionLeft" format="dimension" />
<attr name="additionRight" format="dimension" />
<attr name="additionTop" format="dimension" />
</declare-styleable>
</resources>
Button實現:
public class LargeTouchableAreasButton extends Button {
private final int TOUCH_ADDITION = 0;
private int mTouchAdditionBottom = 0;
private int mTouchAdditionLeft = 0;
private int mTouchAdditionRight = 0;
private int mTouchAdditionTop = 0;
private int mPreviousLeft = -1;
private int mPreviousRight = -1;
private int mPreviousBottom = -1;
private int mPreviousTop = -1;
public LargeTouchableAreasButton(Context context) {
super(context);
}
public LargeTouchableAreasButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public LargeTouchableAreasButton(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.LargeTouchableAreaView);
int addition = (int) a.getDimension(
R.styleable.LargeTouchableAreaView_addition, TOUCH_ADDITION);
mTouchAdditionBottom = addition;
mTouchAdditionLeft = addition;
mTouchAdditionRight = addition;
mTouchAdditionTop = addition;
mTouchAdditionBottom = (int) a.getDimension(
R.styleable.LargeTouchableAreaView_additionBottom,
mTouchAdditionBottom);
mTouchAdditionLeft = (int) a.getDimension(
R.styleable.LargeTouchableAreaView_additionLeft,
mTouchAdditionLeft);
mTouchAdditionRight = (int) a.getDimension(
R.styleable.LargeTouchableAreaView_additionRight,
mTouchAdditionRight);
mTouchAdditionTop = (int) a.getDimension(
R.styleable.LargeTouchableAreaView_additionTop,
mTouchAdditionTop);
a.recycle();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (left != mPreviousLeft || top != mPreviousTop
|| right != mPreviousRight || bottom != mPreviousBottom) {
mPreviousLeft = left;
mPreviousTop = top;
mPreviousRight = right;
mPreviousBottom = bottom;
final View parent = (View) this.getParent();
parent.setTouchDelegate(new TouchDelegate(new Rect(left
- mTouchAdditionLeft, top - mTouchAdditionTop, right
+ mTouchAdditionRight, bottom + mTouchAdditionBottom), this));
}
}
}
然后在具體要使用到這個Button的xml中加上以下代碼:
xmlns:lta="http://schemas.android.com/apk/res/com.xxx.xxx"
其中"lta"這個名字可以隨便取,最后的是你的app包名。
最后在這個Button中定義希望增大的尺寸:
<com.xxx.LargeTouchableAreasButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
lta:addition="30dp" />
大功告成。
但這個自定義的View并不是完美的,還存在以下問題:
1、必須保證parent足夠大,如果自定義的范圍超出parent的大小,則超出的那部分無效。
2、一個parent只能設置一個觸摸委派,設置多個時,只有最后設置的child有效。如果希望一個view能設置多個委派,需要再自定義parent,具體方法可參考:鏈接地址
總而言之,要觸發(fā)委派,必須保證parent接收到了觸摸事件,并且落在了你定義的范圍內。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android實現RecyclerView嵌套流式布局的詳細過程
最近在做需求的時候,碰到有各種篩選項的界面,下面這篇文章主要給大家介紹了關于Android實現RecyclerView嵌套流式布局的詳細過程,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2022-12-12

