Android Touch系统简介(二):实例详解onInterceptTouchEvent与onT
2019獨角獸企業重金招聘Python工程師標準>>>
上一篇文章主要講述了Android的TouchEvent的分發過程,其中有兩個重要的函數:onInterceptTouchEvent和onTouchEvent,這兩個函數可被重裝以完成特定的邏輯。onInterceptTouchEvent的定義為于ViewGroup中,默認返回值為false,表示不攔截TouchEvent。onTouchEvent的定義位于View中,當ViewGroup要調用onTouchEvent時,會利用super.onTouchEvent。ViewGroup調用onTouchEvent默認返回false,表示不消耗touch事件,View調用onTouchEvent默認返回true,表示消耗了touch事件。考慮到onInterceptTouchEvent與onTouchEven在寫UI的時候經常會用到,下面以一個例子來講解一下。
先創建一個類MyView,繼承自View
[java]?view plaincopy
public?class?MyView?extends?Button?{??
????private?static?final?String?TAG?=?MyView.class.getName();??
??
????public?MyView(Context?context){??
????????super(context);??
????}??
??
????public?MyView(Context?context,?AttributeSet?attrs)?{??
????????super(context,?attrs);??
????}??
??
????@Override??
????public?boolean?onTouchEvent(MotionEvent?event)?{??
????????Log.d(TAG,?"onTouchEvent.");??
????????LogUtil.logAction(event,?TAG);??
????????return?super.onTouchEvent(event);??
????}??
}??
創建類MyLayout,繼承自ViewGroup
[java]?view plaincopy
public?class?MyLayout?extends?FrameLayout{??
????private?static?final?String?TAG?=?MyLayout.class.getName();??
??
????public?MyLayout(Context?context)?{??
????????super(context);??
????}??
??
????public?MyLayout(Context?context,?AttributeSet?attributeSet)?{??
????????super(context,?attributeSet);??
????}??
??
????@Override??
????public?boolean?onInterceptTouchEvent(MotionEvent?ev)?{??
????????Log.d(TAG,?"onInterceptTouchEvent");??
??
????????return?super.onInterceptTouchEvent(ev);??
????}??
??
????@Override??
????public?boolean?onTouchEvent(MotionEvent?event)?{??
????????Log.d(TAG,?"onTouchEvent.");??
????????LogUtil.logAction(event,?TAG);??
????????return?super.onTouchEvent(event);??
????}??
}??
LogUtil.logAction()函數是用來打印MotionEvent的動作類型,代碼如下:
[java]?view plaincopy
public?class?LogUtil?{??
????public?static?void?logAction(MotionEvent?event,?final?String?tag)?{??
????????int?action?=?event.getAction();??
????????switch(action)?{??
????????????case?MotionEvent.ACTION_DOWN:??
????????????????Log.d(tag,?"action?down");??
????????????????break;??
????????????case?MotionEvent.ACTION_CANCEL:??
????????????????Log.d(tag,?"action?cancel");??
????????????????break;??
????????????case?MotionEvent.ACTION_UP:??
????????????????Log.d(tag,?"action?up");??
????????????????break;??
????????????case?MotionEvent.ACTION_MOVE:??
????????????????Log.d(tag,?"action?move");??
????????????????break;??
????????????default:??
????????????????Log.d(tag,?"unknow?action");??
????????}??
????}??
}??
布局文件main.xml將MyView嵌套在MyLayout中,代碼如下:
[html]?view plaincopy
<view?android:layout_width="fill_parent"??
??????android:layout_height="fill_parent"??
??????class="com.example.AndroidTest.MyLayout"?xmlns:android="http://schemas.android.com/apk/res/android"??
??????android:id="@+id/view">??
????<com.example.AndroidTest.MyView??
????????????android:layout_width="fill_parent"??
????????????android:layout_height="wrap_content"??
????????????android:text="hello"?/>??
??????
</view>??
MainActivity的代碼如下:
[java]?view plaincopy
public?class?MainActivity?extends?Activity?{??
????public?static?final?String?TAG?=?"TouchDemoActivity";??
????@Override??
????public?void?onCreate(Bundle?savedInstanceState)??
????{??
????????super.onCreate(savedInstanceState);??
????????setContentView(R.layout.main);??
????}??
??
}??
程序啟動后,截圖如下。
下面分情況討論程序的運行結果。
1、MyLayout的onInterceptTouchEvent返回false,MyView的onTouchEvent返回true
情況1:當點擊藍色框內的任意位置,只有MyLayout會接收事件,輸出的Log如下:
可以看出,touch事件最后會被MyLayout的onTouchEvent接收到。
情況2: 點擊紅色框內的黑色區域,由于onInterceptTouchEvent()返回false,故MyView也能接收到touchEvent事件,輸出的Log如下:
可以看出,由于MyView的onTOuchEvent默認返回True,消耗了touch事件,MyLayout中的onTOuchEvent將不會被調用。
當我們的手指按下黑色區域,停留幾秒再抬起,得到的Log如下圖:
可以看出,第一個事件的類型為action down,最后一個為action up,中間的都是action move的類型,這正好符合上一篇文章介紹的Android的手勢定義。
2、MyLayout的onInterceptTouchEvent返回false,MyView的onTouchEvent返回false
改寫MyView中onTouchEvent的代碼,令其返回false
[java]?view plaincopy
@Override??
public?boolean?onTouchEvent(MotionEvent?event)?{??
????Log.d(TAG,?"onTouchEvent.");??
????LogUtil.logAction(event,?TAG);??
????return?false;??
}??
由于MyView沒有消耗touch事件,MyLayout的onTouchEvent將會被調用,打印的log如下:
可以看出,touch的類型只為action down。
3、MyLayout的onInterceptTouchEvent返回true
改寫MyLayout中的onInterceptTouchEvent代碼,令其返回true
[java]?view plaincopy
@Override??
public?boolean?onInterceptTouchEvent(MotionEvent?ev)?{??
????Log.d(TAG,?"onInterceptTouchEvent");??
??
????return?true;??
}??
由于MyLayout攔截了touch事件,MyView中的onTouchEvent將不會被調用,log如下:
以上對Android的onInterceptTouchEvent和onTouchEvent的描述若有不妥之處,歡迎指正。
本文參考的代碼出自:兩分鐘徹底讓你明白Android中onInterceptTouchEvent與onTouchEvent(圖文)!,感謝作者的無私分享。
轉載于:https://my.oschina.net/fuckboogie/blog/343132
總結
以上是生活随笔為你收集整理的Android Touch系统简介(二):实例详解onInterceptTouchEvent与onT的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android IOS WebRTC 音
- 下一篇: SQL Server插入中文数据后出现乱