Android 開源SlidingMenu的bug修改,androidslidingmenu

來源:互聯網
上載者:User

Android 開源SlidingMenu的bug修改,androidslidingmenu

         SlidingMenu相信大家都已經很熟悉了 ,原始碼託管在 https://github.com/jfeinstein10/SlidingMenu。首先我要感謝下原作者的大無畏精神,因為開源而偉大,哈哈。如果我們的項目中只想用到SlidingMenu,那我們就要把SlidingMenu這個控制項給抽離出來了。這個是我抽離出來的的SlidingMenu控制項原始碼(大家有需要的可以下載學習下)。如下:

         SlidingMenu控制項原始碼

         我也很自豪的將這個開原始檔控制運用在自己公司的項目中了,可是經公司的測試人員測試後,發現一個問題,SlidingMenu來回的快速切換(當SlidingMenu開啟時,一個手指點擊SlidingMenu的下方布局(代碼中:自訂的CustomViewBehind),另一個手指同時點擊SlidingMenu的上方布局(CustomViewAbove)),頻繁的如此操作會出現這個一個現象(不是必現的哦):當SlidingMenu關閉後,任憑我怎麼點擊布局上面的控制項,事件都不響應了,起初以為是應用卡死了,可是按裝置上的退出,應用可以正常退出。那我初步定位原因就是CustomViewAbove這個自訂的ViewGroup把手勢事件給攔截了,以致於子View接受不到事件,就響應不了了。

     那我們可以直接去看SlidingMenu控制項的原始碼了,找到CustomViewAbove.java,然後我們找到這個方法onInterceptTouchEvent(),這個方法是ViewGroup的一個方法,目的是在系統向該ViewGroup及其各個childView觸發onTouchEvent()之前對相關事件進行一次攔截.如果onInterceptTouchEvent返回true,就表示該ViewGroup不會將事件向它的子childView傳遞了;返回false,就不攔截事件了。因此我覺得CustomViewAbove.java中的在上面那個現象中onInterceptTouchEvent方法返回true了,所以各種手勢事件都不響應了。我們看代碼吧:

    @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

if (!mEnabled)
return false;

final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;

if (DEBUG)
if (action == MotionEvent.ACTION_DOWN)
Log.v(TAG, "Received ACTION_DOWN");

if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP
|| (action != MotionEvent.ACTION_DOWN && mIsUnableToDrag)) {
endDrag();
return false;
}

switch (action) {
case MotionEvent.ACTION_MOVE:
determineDrag(ev);
break;
case MotionEvent.ACTION_DOWN:
int index = MotionEventCompat.getActionIndex(ev);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
if (mActivePointerId == INVALID_POINTER)
break;
mLastMotionX = mInitialMotionX = MotionEventCompat.getX(ev, index);
mLastMotionY = MotionEventCompat.getY(ev, index);
if (thisTouchAllowed(ev)) {
mIsBeingDragged = false;
mIsUnableToDrag = false;
if (isMenuOpen() && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) {
mQuickReturn = true;
}
} else {
mIsUnableToDrag = true;
}
break;
case MotionEventCompat.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}

if (!mIsBeingDragged) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
}
return mIsBeingDragged || mQuickReturn;
}
   看原始碼發現,onInterceptTouchEvent返回true或者false是由mIsBeingDragged(是否正在拖拽) 和 mQuickReturn(是否快速返回)兩個成員變數決定的。因此在某個特殊情境下,合理狀況是當SlidngMenu已經

關閉了,那IsBeingDragged和 mQuickReturn應該同時為false,但上述那個現象的原因就是IsBeingDragged或者mQuickReturn為true。說明頻繁的非常規操作,我們沒處理好這兩個變數。看原始碼,我發現每次ACTION_DOWN

時應該置IsBeingDragged和 mQuickReturn為false,因為ACTION_DOWN事件發生時,不可能正在拖拽或者SlidingMenu

快速關閉。見我添加的這兩行代碼(如下):

   case MotionEvent.ACTION_DOWN:
   mIsBeingDragged = false;
   mQuickReturn = false;

    OK,這個BUG就這樣解決了,說明在每次SlidingMenu關閉後IsBeingDragged和 mQuickReturn的值有問題,所以我決定在每次ACTION_DOWN將這兩個變數都置false。原始碼還是很多的,想要全部弄清楚還是要花時間滴,只能先針對現象解決問題啦。






現在android要做側滑功能表列用SlidingMenu開源項目好,還是用android內建的Navigation Drawer好?

如果是學習代碼的話,建議還是學習官方的,不過SlidingMenu有很多功能,比如滑出菜單時控制後面的背景動不動,動多少,貌似Navigation Drawer的背景不能動的。開源項目被官方API取代是趨勢,因為大家都覺得官方的介面用著放心嘛,但開源項目可能更靈活。
 
錯誤提示

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.