Skip to content

Instantly share code, notes, and snippets.

@ixiyang
Last active December 27, 2015 08:49
Show Gist options
  • Save ixiyang/7299728 to your computer and use it in GitHub Desktop.
Save ixiyang/7299728 to your computer and use it in GitHub Desktop.
menudrawer源码摘记
/**
* Attaches the menu drawer to the content view.
*/
private static void attachToContent(Activity activity, MenuDrawer menuDrawer) {
/**
* Do not call mActivity#setContentView.
* E.g. if using with a ListActivity, Activity#setContentView is overridden and dispatched to
* MenuDrawer#setContentView, which then again would call Activity#setContentView.
*/
ViewGroup content = (ViewGroup) activity.findViewById(android.R.id.content);
content.removeAllViews();
content.addView(menuDrawer, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
//android.R.id.content:代表一个内容布局视图层级的根元素
/**
* Attaches the menu drawer to the window.
*/
private static void attachToDecor(Activity activity, MenuDrawer menuDrawer) {
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
decorView.removeAllViews();
decorView.addView(menuDrawer, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
menuDrawer.mContentContainer.addView(decorChild, decorChild.getLayoutParams());
}
//DecorView为整个Window界面的最顶层View。
protected int dpToPx(int dp) {
return (int) (getResources().getDisplayMetrics().density * dp + 0.5f);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int width = r - l;
final int height = b - t;
switch (getPosition()) {
case LEFT:
mMenuContainer.layout(0, 0, mMenuSize, height);
mContentContainer.layout(mMenuSize, 0, width, height);
break;
case RIGHT:
mMenuContainer.layout(width - mMenuSize, 0, width, height);
mContentContainer.layout(0, 0, width - mMenuSize, height);
break;
case TOP:
mMenuContainer.layout(0, 0, width, mMenuSize);
mContentContainer.layout(0, mMenuSize, width, height);
break;
case BOTTOM:
mMenuContainer.layout(0, height - mMenuSize, width, height);
mContentContainer.layout(0, 0, width, height - mMenuSize);
break;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.UNSPECIFIED) {
throw new IllegalStateException("Must measure with an exact size");
}
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int height = MeasureSpec.getSize(heightMeasureSpec);
switch (getPosition()) {
case LEFT:
case RIGHT: {
final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
final int menuWidth = mMenuSize;
final int menuWidthMeasureSpec = MeasureSpec.makeMeasureSpec(menuWidth, MeasureSpec.EXACTLY);
final int contentWidth = width - menuWidth;
final int contentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(contentWidth, MeasureSpec.EXACTLY);
mContentContainer.measure(contentWidthMeasureSpec, childHeightMeasureSpec);
mMenuContainer.measure(menuWidthMeasureSpec, childHeightMeasureSpec);
break;
}
case TOP:
case BOTTOM: {
final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
final int menuHeight = mMenuSize;
final int menuHeightMeasureSpec = MeasureSpec.makeMeasureSpec(menuHeight, MeasureSpec.EXACTLY);
final int contentHeight = height - menuHeight;
final int contentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY);
mContentContainer.measure(childWidthMeasureSpec, contentHeightMeasureSpec);
mMenuContainer.measure(childWidthMeasureSpec, menuHeightMeasureSpec);
break;
}
}
setMeasuredDimension(width, height);
}
/*
onMeasure方法中确定menuContainer和contentContainer的宽度和高度。
onLayout方法中确定menuContainer和contentContainer在整个视图中的位置
*/
protected void cancelContentTouch() {
final long now = SystemClock.uptimeMillis();
final MotionEvent cancelEvent = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
getChildAt(i).dispatchTouchEvent(cancelEvent);
}
mContentContainer.dispatchTouchEvent(cancelEvent);
cancelEvent.recycle();
}
/*
SystemClock.uptimeMillis()
Returns milliseconds since boot, not counting time spent in deep sleep.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment