Android Touch系統簡介(二):執行個體詳解onInterceptTouchEvent與onTouchEvent的調用過程

來源:互聯網
上載者:User

上一篇文章主要講述了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

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

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的動作類型,代碼如下:

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中,代碼如下:

        
MainActivity的代碼如下:

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<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjwvcD4KPHA+x+m/9jGjurWxteO798C2yau/8sTatcTIztLizrvWw6Os1rvT0E15TGF5b3V0u+G908rVysK8/qOsyuSz9rXETG9nyOfPwqO6PC9wPgo8cD48aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20140522/20140522091501145.jpg" alt="\">
可以看出,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

    @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

    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        Log.d(TAG, "onInterceptTouchEvent");        return true;    }
由於MyLayout攔截了touch事件,MyView中的onTouchEvent將不會被調用,log如下:

Android的onInterceptTouchEvent和onTouchEvent的描述若有不妥之處,歡迎指正。

本文參考的代碼出自:兩分鐘徹底讓你明白Android中onInterceptTouchEvent與onTouchEvent(圖文)!,感謝作者的無私分享。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.