當前位置:
首頁 > 知識 > 自定義View——可刪除 item 的 ListView(事件分發)

自定義View——可刪除 item 的 ListView(事件分發)

事件分發概述

Android 中觸摸事件主要由 dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent 來控制。

觸摸屏幕時,首先會觸發 ViewGroup 的 dispathTouchEvent 方法,自定義 View 時,如果它在 ACTION_DOWN 返回 false, 則表示不再繼續向下執行,事件到此結束,如果返回了 true, 則下次繼續執行 dispatchTouchEvent 方法,返回 super.dispatchTouchEvent(ev) 則會執行 onInterceptTouchEvent/onTouchEvent.

View 是沒有 onInterceptTouchEvent 方法的,因為事件傳遞到 View 之後是一定交給自己處理了。ViewGroup 的 onInterceptTouchEvent 方法 返回 true 表示 要攔截事件,給自己處理,返回 false 表示不攔截,傳遞給子 View 處理,執行子 View 的 dispatchTouchEvent 方法。

執行到 onTouchEvent 方法,返回 true 表示不再給它的 ViewGroup 處理,自己處理完就結束,返回 false 表示自己可以做一些操作,再執行它的 ViewGroup 的 onTouchEvent 方法。

可刪除 item 的 ListView 思路

理解上面的描述之後,就可以結合上面文章中的例子來自己動手實現一個

從右向左滑動時,需要我們來處理(彈出PopupWindow),其餘的交由 ListView 處理

PopupWindow 是彈出狀態時,再次觸摸,則需要消失 PopupWindow, 事件到此結束

這裡貼出 dispatchTouchEvent 和 onTouchEvent 的代碼:

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

Log.e("ItemDeletableListView", "dispatchTouchEvent action : " + ev.getAction() + ", handleTouchEvent:" + handleTouchEvent + ", isPopupShow:" + isPopupShow);

Log.e("ItemDeletableListView", "dispatchTouchEvent mPwDelete.isShowing:" + mPwDelete.isShowing());

if (!handleTouchEvent) {

// 如果不需要處理觸摸事件,那麼久不做處理

return super.dispatchTouchEvent(ev);

}

switch (ev.getAction()) {

case MotionEvent.ACTION_DOWN:

if (isPopupShow) {

// 已經展示了 popup 的話,再次觸發 down 事件,則消失,並不再分發事件

mPwDelete.dismiss();

isPopupShow = false;

return false;

}

downX = ev.getX();

downY = ev.getY();

downPosition = pointToPosition(((int) downX), ((int) downY));

break;

case MotionEvent.ACTION_MOVE:

if (isPopupShow) {

// 如果 move 過程中展示了 popupwindow, 那麼不再分發事件

return false;

}

x = ev.getX();

y = ev.getY();

if (downX-x > touchSlop && downX-x > Math.abs(downY-y)) {

isSliding = true;

} else {

isSliding = false;

}

break;

case MotionEvent.ACTION_UP:

isSliding = false;

break;

}

return super.dispatchTouchEvent(ev);

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

Log.e("ItemDeletableListView", "onTouchEvent action : " + ev.getAction() + ", isSliding:" + isSliding + ", downPosition:" + downPosition);

switch (ev.getAction()) {

case MotionEvent.ACTION_MOVE:

if (isSliding) {

View child = getChildAt(downPosition);

if (child == null) {

return super.onTouchEvent(ev);

}

isPopupShow = true;

int x = getWidth()/2+mPwDelete.getWidth()/2;

int y = child.getTop()+child.getHeight()/2;

Log.e("TAG", "popup x:" + x + ", y:" + y);

mPwDelete.showAtLocation(child, Gravity.TOP | Gravity.LEFT, x, y);

mPwDelete.update();

mTvDelete.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

mDeleteItemListener.deleteItem(downPosition);

mPwDelete.dismiss();

isPopupShow = false;

}

});

}

break;

case MotionEvent.ACTION_UP:

break;

}

return super.onTouchEvent(ev);

}

自定義View——可刪除 item 的 ListView(事件分發)

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

json schema
分散式框架spring-session實現session一致性使用問題

TAG:程序員小新人學習 |