編輯:關於Android編程
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缺省的ExpandableListView的group header無法固定在界面上,當向下滾動後,不能對當前顯示的那些child 指示出它們歸屬
ListView雖然使用廣泛,但系統原生的ListView顯然是不能滿足用戶在審美、功能上不斷提高的需求。不過也不要緊,Android完全可以定制化,讓我們非常方便地對原
關於使用MarkDown編輯器的原因 其實前段時間就支持使用MarkDown編輯器來寫博客了,只是由於當時接觸過MarkDown,所以之前的博客都是使用默認的HTML編輯
Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用戶體驗, 同時也為程序員帶來新的負擔. 動態權限管理就是這樣, 一方面讓用戶更加容易的控制自己