|
|
@@ -1,1652 +0,0 @@
|
|
|
-package net.simonvt.menudrawer;
|
|
|
-
|
|
|
-import net.simonvt.menudrawer.compat.ActionBarHelper;
|
|
|
-
|
|
|
-import android.app.Activity;
|
|
|
-import android.content.Context;
|
|
|
-import android.content.res.TypedArray;
|
|
|
-import android.graphics.Bitmap;
|
|
|
-import android.graphics.BitmapFactory;
|
|
|
-import android.graphics.Canvas;
|
|
|
-import android.graphics.Rect;
|
|
|
-import android.graphics.drawable.Drawable;
|
|
|
-import android.graphics.drawable.GradientDrawable;
|
|
|
-import android.os.Build;
|
|
|
-import android.os.Bundle;
|
|
|
-import android.os.Parcel;
|
|
|
-import android.os.Parcelable;
|
|
|
-import android.util.AttributeSet;
|
|
|
-import android.util.Log;
|
|
|
-import android.view.LayoutInflater;
|
|
|
-import android.view.View;
|
|
|
-import android.view.ViewGroup;
|
|
|
-import android.view.ViewParent;
|
|
|
-import android.view.ViewTreeObserver;
|
|
|
-import android.view.animation.AccelerateInterpolator;
|
|
|
-import android.view.animation.Interpolator;
|
|
|
-
|
|
|
-public abstract class MenuDrawer extends ViewGroup {
|
|
|
-
|
|
|
- /**
|
|
|
- * Callback interface for changing state of the drawer.
|
|
|
- */
|
|
|
- public interface OnDrawerStateChangeListener {
|
|
|
-
|
|
|
- /**
|
|
|
- * Called when the drawer state changes.
|
|
|
- *
|
|
|
- * @param oldState The old drawer state.
|
|
|
- * @param newState The new drawer state.
|
|
|
- */
|
|
|
- void onDrawerStateChange(int oldState, int newState);
|
|
|
-
|
|
|
- /**
|
|
|
- * Called when the drawer slides.
|
|
|
- *
|
|
|
- * @param openRatio Ratio for how open the menu is.
|
|
|
- * @param offsetPixels Current offset of the menu in pixels.
|
|
|
- */
|
|
|
- void onDrawerSlide(float openRatio, int offsetPixels);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Callback that is invoked when the drawer is in the process of deciding whether it should intercept the touch
|
|
|
- * event. This lets the listener decide if the pointer is on a view that would disallow dragging of the drawer.
|
|
|
- * This is only called when the touch mode is {@link #TOUCH_MODE_FULLSCREEN}.
|
|
|
- */
|
|
|
- public interface OnInterceptMoveEventListener {
|
|
|
-
|
|
|
- /**
|
|
|
- * Called for each child the pointer i on when the drawer is deciding whether to intercept the touch event.
|
|
|
- *
|
|
|
- * @param v View to test for draggability
|
|
|
- * @param delta Delta drag in pixels
|
|
|
- * @param x X coordinate of the active touch point
|
|
|
- * @param y Y coordinate of the active touch point
|
|
|
- * @return true if view is draggable by delta dx.
|
|
|
- */
|
|
|
- boolean isViewDraggable(View v, int delta, int x, int y);
|
|
|
- }
|
|
|
-
|
|
|
- public enum Type {
|
|
|
- /**
|
|
|
- * Positions the drawer behind the content.
|
|
|
- */
|
|
|
- BEHIND,
|
|
|
-
|
|
|
- /**
|
|
|
- * A static drawer that can not be dragged.
|
|
|
- */
|
|
|
- STATIC,
|
|
|
-
|
|
|
- /**
|
|
|
- * Positions the drawer on top of the content.
|
|
|
- */
|
|
|
- OVERLAY,
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Tag used when logging.
|
|
|
- */
|
|
|
- private static final String TAG = "MenuDrawer";
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether debug code should be enabled.
|
|
|
- */
|
|
|
- private static final boolean DEBUG = false;
|
|
|
-
|
|
|
- /**
|
|
|
- * The time between each frame when animating the drawer.
|
|
|
- */
|
|
|
- protected static final int ANIMATION_DELAY = 1000 / 60;
|
|
|
-
|
|
|
- /**
|
|
|
- * The default touch bezel size of the drawer in dp.
|
|
|
- */
|
|
|
- private static final int DEFAULT_DRAG_BEZEL_DP = 24;
|
|
|
-
|
|
|
- /**
|
|
|
- * The default drop shadow size in dp.
|
|
|
- */
|
|
|
- private static final int DEFAULT_DROP_SHADOW_DP = 6;
|
|
|
-
|
|
|
- /**
|
|
|
- * Drag mode for sliding only the content view.
|
|
|
- */
|
|
|
- public static final int MENU_DRAG_CONTENT = 0;
|
|
|
-
|
|
|
- /**
|
|
|
- * Drag mode for sliding the entire window.
|
|
|
- */
|
|
|
- public static final int MENU_DRAG_WINDOW = 1;
|
|
|
-
|
|
|
- /**
|
|
|
- * Disallow opening the drawer by dragging the screen.
|
|
|
- */
|
|
|
- public static final int TOUCH_MODE_NONE = 0;
|
|
|
-
|
|
|
- /**
|
|
|
- * Allow opening drawer only by dragging on the edge of the screen.
|
|
|
- */
|
|
|
- public static final int TOUCH_MODE_BEZEL = 1;
|
|
|
-
|
|
|
- /**
|
|
|
- * Allow opening drawer by dragging anywhere on the screen.
|
|
|
- */
|
|
|
- public static final int TOUCH_MODE_FULLSCREEN = 2;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates that the drawer is currently closed.
|
|
|
- */
|
|
|
- public static final int STATE_CLOSED = 0;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates that the drawer is currently closing.
|
|
|
- */
|
|
|
- public static final int STATE_CLOSING = 1;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates that the drawer is currently being dragged by the user.
|
|
|
- */
|
|
|
- public static final int STATE_DRAGGING = 2;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates that the drawer is currently opening.
|
|
|
- */
|
|
|
- public static final int STATE_OPENING = 4;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates that the drawer is currently open.
|
|
|
- */
|
|
|
- public static final int STATE_OPEN = 8;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether to use {@link View#setTranslationX(float)} when positioning views.
|
|
|
- */
|
|
|
- static final boolean USE_TRANSLATIONS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
|
|
-
|
|
|
- /**
|
|
|
- * Time to animate the indicator to the new active view.
|
|
|
- */
|
|
|
- static final int INDICATOR_ANIM_DURATION = 800;
|
|
|
-
|
|
|
- /**
|
|
|
- * The maximum animation duration.
|
|
|
- */
|
|
|
- private static final int DEFAULT_ANIMATION_DURATION = 600;
|
|
|
-
|
|
|
- /**
|
|
|
- * Interpolator used when animating the drawer open/closed.
|
|
|
- */
|
|
|
- protected static final Interpolator SMOOTH_INTERPOLATOR = new SmoothInterpolator();
|
|
|
-
|
|
|
- /**
|
|
|
- * Interpolator used for stretching/retracting the active indicator.
|
|
|
- */
|
|
|
- protected static final Interpolator INDICATOR_INTERPOLATOR = new AccelerateInterpolator();
|
|
|
-
|
|
|
- /**
|
|
|
- * Drawable used as menu overlay.
|
|
|
- */
|
|
|
- protected Drawable mMenuOverlay;
|
|
|
-
|
|
|
- /**
|
|
|
- * Defines whether the drop shadow is enabled.
|
|
|
- */
|
|
|
- protected boolean mDropShadowEnabled;
|
|
|
-
|
|
|
- /**
|
|
|
- * The color of the drop shadow.
|
|
|
- */
|
|
|
- protected int mDropShadowColor;
|
|
|
-
|
|
|
- /**
|
|
|
- * Drawable used as content drop shadow onto the menu.
|
|
|
- */
|
|
|
- protected Drawable mDropShadowDrawable;
|
|
|
-
|
|
|
- private boolean mCustomDropShadow;
|
|
|
-
|
|
|
- /**
|
|
|
- * The size of the content drop shadow.
|
|
|
- */
|
|
|
- protected int mDropShadowSize;
|
|
|
-
|
|
|
- /**
|
|
|
- * Bitmap used to indicate the active view.
|
|
|
- */
|
|
|
- protected Bitmap mActiveIndicator;
|
|
|
-
|
|
|
- /**
|
|
|
- * The currently active view.
|
|
|
- */
|
|
|
- protected View mActiveView;
|
|
|
-
|
|
|
- /**
|
|
|
- * Position of the active view. This is compared to View#getTag(R.id.mdActiveViewPosition) when drawing the
|
|
|
- * indicator.
|
|
|
- */
|
|
|
- protected int mActivePosition;
|
|
|
-
|
|
|
- /**
|
|
|
- * Whether the indicator should be animated between positions.
|
|
|
- */
|
|
|
- private boolean mAllowIndicatorAnimation;
|
|
|
-
|
|
|
- /**
|
|
|
- * Used when reading the position of the active view.
|
|
|
- */
|
|
|
- protected final Rect mActiveRect = new Rect();
|
|
|
-
|
|
|
- /**
|
|
|
- * Temporary {@link Rect} used for deciding whether the view should be invalidated so the indicator can be redrawn.
|
|
|
- */
|
|
|
- private final Rect mTempRect = new Rect();
|
|
|
-
|
|
|
- /**
|
|
|
- * The custom menu view set by the user.
|
|
|
- */
|
|
|
- private View mMenuView;
|
|
|
-
|
|
|
- /**
|
|
|
- * The parent of the menu view.
|
|
|
- */
|
|
|
- protected BuildLayerFrameLayout mMenuContainer;
|
|
|
-
|
|
|
- /**
|
|
|
- * The parent of the content view.
|
|
|
- */
|
|
|
- protected BuildLayerFrameLayout mContentContainer;
|
|
|
-
|
|
|
- /**
|
|
|
- * The size of the menu (width or height depending on the gravity).
|
|
|
- */
|
|
|
- protected int mMenuSize;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether the menu is currently visible.
|
|
|
- */
|
|
|
- protected boolean mMenuVisible;
|
|
|
-
|
|
|
- /**
|
|
|
- * The drag mode of the drawer. Can be either {@link #MENU_DRAG_CONTENT} or {@link #MENU_DRAG_WINDOW}.
|
|
|
- */
|
|
|
- private int mDragMode = MENU_DRAG_CONTENT;
|
|
|
-
|
|
|
- /**
|
|
|
- * The current drawer state.
|
|
|
- *
|
|
|
- * @see #STATE_CLOSED
|
|
|
- * @see #STATE_CLOSING
|
|
|
- * @see #STATE_DRAGGING
|
|
|
- * @see #STATE_OPENING
|
|
|
- * @see #STATE_OPEN
|
|
|
- */
|
|
|
- protected int mDrawerState = STATE_CLOSED;
|
|
|
-
|
|
|
- /**
|
|
|
- * The touch bezel size of the drawer in px.
|
|
|
- */
|
|
|
- protected int mTouchBezelSize;
|
|
|
-
|
|
|
- /**
|
|
|
- * The touch area size of the drawer in px.
|
|
|
- */
|
|
|
- protected int mTouchSize;
|
|
|
-
|
|
|
- /**
|
|
|
- * Listener used to dispatch state change events.
|
|
|
- */
|
|
|
- private OnDrawerStateChangeListener mOnDrawerStateChangeListener;
|
|
|
-
|
|
|
- /**
|
|
|
- * Touch mode for the Drawer.
|
|
|
- * Possible values are {@link #TOUCH_MODE_NONE}, {@link #TOUCH_MODE_BEZEL} or {@link #TOUCH_MODE_FULLSCREEN}
|
|
|
- * Default: {@link #TOUCH_MODE_BEZEL}
|
|
|
- */
|
|
|
- protected int mTouchMode = TOUCH_MODE_BEZEL;
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether to use {@link View#LAYER_TYPE_HARDWARE} when animating the drawer.
|
|
|
- */
|
|
|
- protected boolean mHardwareLayersEnabled = true;
|
|
|
-
|
|
|
- /**
|
|
|
- * The Activity the drawer is attached to.
|
|
|
- */
|
|
|
- private Activity mActivity;
|
|
|
-
|
|
|
- /**
|
|
|
- * Scroller used when animating the indicator to a new position.
|
|
|
- */
|
|
|
- private FloatScroller mIndicatorScroller;
|
|
|
-
|
|
|
- /**
|
|
|
- * Runnable used when animating the indicator to a new position.
|
|
|
- */
|
|
|
- private Runnable mIndicatorRunnable = new Runnable() {
|
|
|
- @Override
|
|
|
- public void run() {
|
|
|
- animateIndicatorInvalidate();
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- /**
|
|
|
- * The start position of the indicator when animating it to a new position.
|
|
|
- */
|
|
|
- protected int mIndicatorStartPos;
|
|
|
-
|
|
|
- /**
|
|
|
- * [0..1] value indicating the current progress of the animation.
|
|
|
- */
|
|
|
- protected float mIndicatorOffset;
|
|
|
-
|
|
|
- /**
|
|
|
- * Whether the indicator is currently animating.
|
|
|
- */
|
|
|
- protected boolean mIndicatorAnimating;
|
|
|
-
|
|
|
- /**
|
|
|
- * Bundle used to hold the drawers state.
|
|
|
- */
|
|
|
- protected Bundle mState;
|
|
|
-
|
|
|
- /**
|
|
|
- * The maximum duration of open/close animations.
|
|
|
- */
|
|
|
- protected int mMaxAnimationDuration = DEFAULT_ANIMATION_DURATION;
|
|
|
-
|
|
|
- /**
|
|
|
- * Callback that lets the listener override intercepting of touch events.
|
|
|
- */
|
|
|
- protected OnInterceptMoveEventListener mOnInterceptMoveEventListener;
|
|
|
-
|
|
|
- protected SlideDrawable mSlideDrawable;
|
|
|
-
|
|
|
- protected Drawable mThemeUpIndicator;
|
|
|
-
|
|
|
- protected boolean mDrawerIndicatorEnabled;
|
|
|
-
|
|
|
- private ActionBarHelper mActionBarHelper;
|
|
|
-
|
|
|
- private int mCurrentUpContentDesc;
|
|
|
-
|
|
|
- private int mDrawerOpenContentDesc;
|
|
|
-
|
|
|
- private int mDrawerClosedContentDesc;
|
|
|
-
|
|
|
- /**
|
|
|
- * The position of the drawer.
|
|
|
- */
|
|
|
- private Position mPosition;
|
|
|
-
|
|
|
- private Position mResolvedPosition;
|
|
|
-
|
|
|
- private final Rect mIndicatorClipRect = new Rect();
|
|
|
-
|
|
|
- protected boolean mIsStatic;
|
|
|
-
|
|
|
- protected final Rect mDropShadowRect = new Rect();
|
|
|
-
|
|
|
- /**
|
|
|
- * Current offset.
|
|
|
- */
|
|
|
- protected float mOffsetPixels;
|
|
|
-
|
|
|
- /**
|
|
|
- * Whether an overlay should be drawn as the drawer is opened and closed.
|
|
|
- */
|
|
|
- protected boolean mDrawOverlay;
|
|
|
-
|
|
|
- /**
|
|
|
- * Attaches the MenuDrawer to the Activity.
|
|
|
- *
|
|
|
- * @param activity The activity that the MenuDrawer will be attached to.
|
|
|
- * @return The created MenuDrawer instance.
|
|
|
- */
|
|
|
- public static MenuDrawer attach(Activity activity) {
|
|
|
- return attach(activity, Type.BEHIND);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Attaches the MenuDrawer to the Activity.
|
|
|
- *
|
|
|
- * @param activity The activity the menu drawer will be attached to.
|
|
|
- * @param type The {@link Type} of the drawer.
|
|
|
- * @return The created MenuDrawer instance.
|
|
|
- */
|
|
|
- public static MenuDrawer attach(Activity activity, Type type) {
|
|
|
- return attach(activity, type, Position.START);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Attaches the MenuDrawer to the Activity.
|
|
|
- *
|
|
|
- * @param activity The activity the menu drawer will be attached to.
|
|
|
- * @param position Where to position the menu.
|
|
|
- * @return The created MenuDrawer instance.
|
|
|
- */
|
|
|
- public static MenuDrawer attach(Activity activity, Position position) {
|
|
|
- return attach(activity, Type.BEHIND, position);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Attaches the MenuDrawer to the Activity.
|
|
|
- *
|
|
|
- * @param activity The activity the menu drawer will be attached to.
|
|
|
- * @param type The {@link Type} of the drawer.
|
|
|
- * @param position Where to position the menu.
|
|
|
- * @return The created MenuDrawer instance.
|
|
|
- */
|
|
|
- public static MenuDrawer attach(Activity activity, Type type, Position position) {
|
|
|
- return attach(activity, type, position, MENU_DRAG_CONTENT);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Attaches the MenuDrawer to the Activity.
|
|
|
- *
|
|
|
- * @param activity The activity the menu drawer will be attached to.
|
|
|
- * @param type The {@link Type} of the drawer.
|
|
|
- * @param position Where to position the menu.
|
|
|
- * @param dragMode The drag mode of the drawer. Can be either {@link MenuDrawer#MENU_DRAG_CONTENT}
|
|
|
- * or {@link MenuDrawer#MENU_DRAG_WINDOW}.
|
|
|
- * @return The created MenuDrawer instance.
|
|
|
- */
|
|
|
- public static MenuDrawer attach(Activity activity, Type type, Position position, int dragMode) {
|
|
|
- MenuDrawer menuDrawer = createMenuDrawer(activity, dragMode, position, type);
|
|
|
- menuDrawer.setId(R.id.md__drawer);
|
|
|
-
|
|
|
- switch (dragMode) {
|
|
|
- case MenuDrawer.MENU_DRAG_CONTENT:
|
|
|
- attachToContent(activity, menuDrawer);
|
|
|
- break;
|
|
|
-
|
|
|
- case MenuDrawer.MENU_DRAG_WINDOW:
|
|
|
- attachToDecor(activity, menuDrawer);
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- throw new RuntimeException("Unknown menu mode: " + dragMode);
|
|
|
- }
|
|
|
-
|
|
|
- return menuDrawer;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Constructs the appropriate MenuDrawer based on the position.
|
|
|
- */
|
|
|
- private static MenuDrawer createMenuDrawer(Activity activity, int dragMode, Position position, Type type) {
|
|
|
- MenuDrawer drawer;
|
|
|
-
|
|
|
- if (type == Type.STATIC) {
|
|
|
- drawer = new StaticDrawer(activity);
|
|
|
-
|
|
|
- } else if (type == Type.OVERLAY) {
|
|
|
- drawer = new OverlayDrawer(activity, dragMode);
|
|
|
- if (position == Position.LEFT || position == Position.START) {
|
|
|
- drawer.setupUpIndicator(activity);
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
- drawer = new SlidingDrawer(activity, dragMode);
|
|
|
- if (position == Position.LEFT || position == Position.START) {
|
|
|
- drawer.setupUpIndicator(activity);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- drawer.mDragMode = dragMode;
|
|
|
- drawer.setPosition(position);
|
|
|
-
|
|
|
- return drawer;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 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);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 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());
|
|
|
- }
|
|
|
-
|
|
|
- MenuDrawer(Activity activity, int dragMode) {
|
|
|
- this(activity);
|
|
|
-
|
|
|
- mActivity = activity;
|
|
|
- mDragMode = dragMode;
|
|
|
- }
|
|
|
-
|
|
|
- public MenuDrawer(Context context) {
|
|
|
- this(context, null);
|
|
|
- }
|
|
|
-
|
|
|
- public MenuDrawer(Context context, AttributeSet attrs) {
|
|
|
- this(context, attrs, R.attr.menuDrawerStyle);
|
|
|
- }
|
|
|
-
|
|
|
- public MenuDrawer(Context context, AttributeSet attrs, int defStyle) {
|
|
|
- super(context, attrs, defStyle);
|
|
|
- initDrawer(context, attrs, defStyle);
|
|
|
- }
|
|
|
-
|
|
|
- protected void initDrawer(Context context, AttributeSet attrs, int defStyle) {
|
|
|
- setWillNotDraw(false);
|
|
|
- setFocusable(false);
|
|
|
-
|
|
|
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MenuDrawer, R.attr.menuDrawerStyle,
|
|
|
- R.style.Widget_MenuDrawer);
|
|
|
-
|
|
|
- final Drawable contentBackground = a.getDrawable(R.styleable.MenuDrawer_mdContentBackground);
|
|
|
- final Drawable menuBackground = a.getDrawable(R.styleable.MenuDrawer_mdMenuBackground);
|
|
|
-
|
|
|
- mMenuSize = a.getDimensionPixelSize(R.styleable.MenuDrawer_mdMenuSize, dpToPx(240));
|
|
|
-
|
|
|
- final int indicatorResId = a.getResourceId(R.styleable.MenuDrawer_mdActiveIndicator, 0);
|
|
|
- if (indicatorResId != 0) {
|
|
|
- mActiveIndicator = BitmapFactory.decodeResource(getResources(), indicatorResId);
|
|
|
- }
|
|
|
-
|
|
|
- mDropShadowEnabled = a.getBoolean(R.styleable.MenuDrawer_mdDropShadowEnabled, true);
|
|
|
-
|
|
|
- mDropShadowDrawable = a.getDrawable(R.styleable.MenuDrawer_mdDropShadow);
|
|
|
-
|
|
|
- if (mDropShadowDrawable == null) {
|
|
|
- mDropShadowColor = a.getColor(R.styleable.MenuDrawer_mdDropShadowColor, 0xFF000000);
|
|
|
- } else {
|
|
|
- mCustomDropShadow = true;
|
|
|
- }
|
|
|
-
|
|
|
- mDropShadowSize = a.getDimensionPixelSize(R.styleable.MenuDrawer_mdDropShadowSize,
|
|
|
- dpToPx(DEFAULT_DROP_SHADOW_DP));
|
|
|
-
|
|
|
- mTouchBezelSize = a.getDimensionPixelSize(R.styleable.MenuDrawer_mdTouchBezelSize,
|
|
|
- dpToPx(DEFAULT_DRAG_BEZEL_DP));
|
|
|
-
|
|
|
- mAllowIndicatorAnimation = a.getBoolean(R.styleable.MenuDrawer_mdAllowIndicatorAnimation, false);
|
|
|
-
|
|
|
- mMaxAnimationDuration = a.getInt(R.styleable.MenuDrawer_mdMaxAnimationDuration, DEFAULT_ANIMATION_DURATION);
|
|
|
-
|
|
|
- final int slideDrawableResId = a.getResourceId(R.styleable.MenuDrawer_mdSlideDrawable, -1);
|
|
|
- if (slideDrawableResId != -1) {
|
|
|
- setSlideDrawable(slideDrawableResId);
|
|
|
- }
|
|
|
-
|
|
|
- mDrawerOpenContentDesc = a.getResourceId(R.styleable.MenuDrawer_mdDrawerOpenUpContentDescription, 0);
|
|
|
- mDrawerClosedContentDesc = a.getResourceId(R.styleable.MenuDrawer_mdDrawerClosedUpContentDescription, 0);
|
|
|
-
|
|
|
- mDrawOverlay = a.getBoolean(R.styleable.MenuDrawer_mdDrawOverlay, true);
|
|
|
-
|
|
|
- final int position = a.getInt(R.styleable.MenuDrawer_mdPosition, 0);
|
|
|
- setPosition(Position.fromValue(position));
|
|
|
-
|
|
|
- a.recycle();
|
|
|
-
|
|
|
- mMenuContainer = new NoClickThroughFrameLayout(context);
|
|
|
- mMenuContainer.setId(R.id.md__menu);
|
|
|
- mMenuContainer.setBackgroundDrawable(menuBackground);
|
|
|
-
|
|
|
- mContentContainer = new NoClickThroughFrameLayout(context);
|
|
|
- mContentContainer.setId(R.id.md__content);
|
|
|
- mContentContainer.setBackgroundDrawable(contentBackground);
|
|
|
-
|
|
|
- mMenuOverlay = new ColorDrawable(0xFF000000);
|
|
|
-
|
|
|
- mIndicatorScroller = new FloatScroller(SMOOTH_INTERPOLATOR);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onFinishInflate() {
|
|
|
- super.onFinishInflate();
|
|
|
- View menu = findViewById(R.id.mdMenu);
|
|
|
- if (menu != null) {
|
|
|
- removeView(menu);
|
|
|
- setMenuView(menu);
|
|
|
- }
|
|
|
-
|
|
|
- View content = findViewById(R.id.mdContent);
|
|
|
- if (content != null) {
|
|
|
- removeView(content);
|
|
|
- setContentView(content);
|
|
|
- }
|
|
|
-
|
|
|
- if (getChildCount() > 2) {
|
|
|
- throw new IllegalStateException(
|
|
|
- "Menu and content view added in xml must have id's @id/mdMenu and @id/mdContent");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected int dpToPx(int dp) {
|
|
|
- return (int) (getResources().getDisplayMetrics().density * dp + 0.5f);
|
|
|
- }
|
|
|
-
|
|
|
- protected boolean isViewDescendant(View v) {
|
|
|
- ViewParent parent = v.getParent();
|
|
|
- while (parent != null) {
|
|
|
- if (parent == this) {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- parent = parent.getParent();
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onAttachedToWindow() {
|
|
|
- super.onAttachedToWindow();
|
|
|
- getViewTreeObserver().addOnScrollChangedListener(mScrollListener);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onDetachedFromWindow() {
|
|
|
- getViewTreeObserver().removeOnScrollChangedListener(mScrollListener);
|
|
|
- super.onDetachedFromWindow();
|
|
|
- }
|
|
|
-
|
|
|
- private boolean shouldDrawIndicator() {
|
|
|
- return mActiveView != null && mActiveIndicator != null && isViewDescendant(mActiveView);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void dispatchDraw(Canvas canvas) {
|
|
|
- super.dispatchDraw(canvas);
|
|
|
- final int offsetPixels = (int) mOffsetPixels;
|
|
|
-
|
|
|
- if (mDrawOverlay && offsetPixels != 0) {
|
|
|
- drawOverlay(canvas);
|
|
|
- }
|
|
|
- if (mDropShadowEnabled && (offsetPixels != 0 || mIsStatic)) {
|
|
|
- drawDropShadow(canvas);
|
|
|
- }
|
|
|
- if (shouldDrawIndicator() && (offsetPixels != 0 || mIsStatic)) {
|
|
|
- drawIndicator(canvas);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected abstract void drawOverlay(Canvas canvas);
|
|
|
-
|
|
|
- private void drawDropShadow(Canvas canvas) {
|
|
|
- // Can't pass the position to the constructor, so wait with loading the drawable until the drop shadow is
|
|
|
- // actually drawn.
|
|
|
- if (mDropShadowDrawable == null) {
|
|
|
- setDropShadowColor(mDropShadowColor);
|
|
|
- }
|
|
|
-
|
|
|
- updateDropShadowRect();
|
|
|
- mDropShadowDrawable.setBounds(mDropShadowRect);
|
|
|
- mDropShadowDrawable.draw(canvas);
|
|
|
- }
|
|
|
-
|
|
|
- protected void updateDropShadowRect() {
|
|
|
- // This updates the rect for the static and sliding drawer. The overlay drawer has its own implementation.
|
|
|
- switch (getPosition()) {
|
|
|
- case LEFT:
|
|
|
- mDropShadowRect.top = 0;
|
|
|
- mDropShadowRect.bottom = getHeight();
|
|
|
- mDropShadowRect.right = ViewHelper.getLeft(mContentContainer);
|
|
|
- mDropShadowRect.left = mDropShadowRect.right - mDropShadowSize;
|
|
|
- break;
|
|
|
-
|
|
|
- case TOP:
|
|
|
- mDropShadowRect.left = 0;
|
|
|
- mDropShadowRect.right = getWidth();
|
|
|
- mDropShadowRect.bottom = ViewHelper.getTop(mContentContainer);
|
|
|
- mDropShadowRect.top = mDropShadowRect.bottom - mDropShadowSize;
|
|
|
- break;
|
|
|
-
|
|
|
- case RIGHT:
|
|
|
- mDropShadowRect.top = 0;
|
|
|
- mDropShadowRect.bottom = getHeight();
|
|
|
- mDropShadowRect.left = ViewHelper.getRight(mContentContainer);
|
|
|
- mDropShadowRect.right = mDropShadowRect.left + mDropShadowSize;
|
|
|
- break;
|
|
|
-
|
|
|
- case BOTTOM:
|
|
|
- mDropShadowRect.left = 0;
|
|
|
- mDropShadowRect.right = getWidth();
|
|
|
- mDropShadowRect.top = ViewHelper.getBottom(mContentContainer);
|
|
|
- mDropShadowRect.bottom = mDropShadowRect.top + mDropShadowSize;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void drawIndicator(Canvas canvas) {
|
|
|
- Integer position = (Integer) mActiveView.getTag(R.id.mdActiveViewPosition);
|
|
|
- final int pos = position == null ? 0 : position;
|
|
|
- if (pos == mActivePosition) {
|
|
|
- updateIndicatorClipRect();
|
|
|
- canvas.save();
|
|
|
- canvas.clipRect(mIndicatorClipRect);
|
|
|
-
|
|
|
- int drawLeft = 0;
|
|
|
- int drawTop = 0;
|
|
|
- switch (getPosition()) {
|
|
|
- case LEFT:
|
|
|
- case TOP:
|
|
|
- drawLeft = mIndicatorClipRect.left;
|
|
|
- drawTop = mIndicatorClipRect.top;
|
|
|
- break;
|
|
|
-
|
|
|
- case RIGHT:
|
|
|
- drawLeft = mIndicatorClipRect.right - mActiveIndicator.getWidth();
|
|
|
- drawTop = mIndicatorClipRect.top;
|
|
|
- break;
|
|
|
-
|
|
|
- case BOTTOM:
|
|
|
- drawLeft = mIndicatorClipRect.left;
|
|
|
- drawTop = mIndicatorClipRect.bottom - mActiveIndicator.getHeight();
|
|
|
- }
|
|
|
-
|
|
|
- canvas.drawBitmap(mActiveIndicator, drawLeft, drawTop, null);
|
|
|
- canvas.restore();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Update the {@link Rect} where the indicator is drawn.
|
|
|
- */
|
|
|
- protected void updateIndicatorClipRect() {
|
|
|
- mActiveView.getDrawingRect(mActiveRect);
|
|
|
- offsetDescendantRectToMyCoords(mActiveView, mActiveRect);
|
|
|
-
|
|
|
- final float openRatio = mIsStatic ? 1.0f : Math.abs(mOffsetPixels) / mMenuSize;
|
|
|
-
|
|
|
- final float interpolatedRatio = 1.f - INDICATOR_INTERPOLATOR.getInterpolation((1.f - openRatio));
|
|
|
-
|
|
|
- final int indicatorWidth = mActiveIndicator.getWidth();
|
|
|
- final int indicatorHeight = mActiveIndicator.getHeight();
|
|
|
-
|
|
|
- final int interpolatedWidth = (int) (indicatorWidth * interpolatedRatio);
|
|
|
- final int interpolatedHeight = (int) (indicatorHeight * interpolatedRatio);
|
|
|
-
|
|
|
- final int startPos = mIndicatorStartPos;
|
|
|
-
|
|
|
- int left = 0;
|
|
|
- int top = 0;
|
|
|
- int right = 0;
|
|
|
- int bottom = 0;
|
|
|
-
|
|
|
- switch (getPosition()) {
|
|
|
- case LEFT:
|
|
|
- case RIGHT:
|
|
|
- final int finalTop = mActiveRect.top + ((mActiveRect.height() - indicatorHeight) / 2);
|
|
|
- if (mIndicatorAnimating) {
|
|
|
- top = (int) (startPos + ((finalTop - startPos) * mIndicatorOffset));
|
|
|
- } else {
|
|
|
- top = finalTop;
|
|
|
- }
|
|
|
- bottom = top + indicatorHeight;
|
|
|
- break;
|
|
|
-
|
|
|
- case TOP:
|
|
|
- case BOTTOM:
|
|
|
- final int finalLeft = mActiveRect.left + ((mActiveRect.width() - indicatorWidth) / 2);
|
|
|
- if (mIndicatorAnimating) {
|
|
|
- left = (int) (startPos + ((finalLeft - startPos) * mIndicatorOffset));
|
|
|
- } else {
|
|
|
- left = finalLeft;
|
|
|
- }
|
|
|
- right = left + indicatorWidth;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- switch (getPosition()) {
|
|
|
- case LEFT: {
|
|
|
- right = ViewHelper.getLeft(mContentContainer);
|
|
|
- left = right - interpolatedWidth;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case TOP: {
|
|
|
- bottom = ViewHelper.getTop(mContentContainer);
|
|
|
- top = bottom - interpolatedHeight;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case RIGHT: {
|
|
|
- left = ViewHelper.getRight(mContentContainer);
|
|
|
- right = left + interpolatedWidth;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case BOTTOM: {
|
|
|
- top = ViewHelper.getBottom(mContentContainer);
|
|
|
- bottom = top + interpolatedHeight;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- mIndicatorClipRect.left = left;
|
|
|
- mIndicatorClipRect.top = top;
|
|
|
- mIndicatorClipRect.right = right;
|
|
|
- mIndicatorClipRect.bottom = bottom;
|
|
|
- }
|
|
|
-
|
|
|
- private void setPosition(Position position) {
|
|
|
- mPosition = position;
|
|
|
- mResolvedPosition = getPosition();
|
|
|
- }
|
|
|
-
|
|
|
- protected Position getPosition() {
|
|
|
- final int layoutDirection = ViewHelper.getLayoutDirection(this);
|
|
|
-
|
|
|
- switch (mPosition) {
|
|
|
- case START:
|
|
|
- if (layoutDirection == LAYOUT_DIRECTION_RTL) {
|
|
|
- return Position.RIGHT;
|
|
|
- } else {
|
|
|
- return Position.LEFT;
|
|
|
- }
|
|
|
-
|
|
|
- case END:
|
|
|
- if (layoutDirection == LAYOUT_DIRECTION_RTL) {
|
|
|
- return Position.LEFT;
|
|
|
- } else {
|
|
|
- return Position.RIGHT;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return mPosition;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onRtlPropertiesChanged(int layoutDirection) {
|
|
|
- super.onRtlPropertiesChanged(layoutDirection);
|
|
|
-
|
|
|
- if (!mCustomDropShadow) setDropShadowColor(mDropShadowColor);
|
|
|
-
|
|
|
- if (getPosition() != mResolvedPosition) {
|
|
|
- mResolvedPosition = getPosition();
|
|
|
- setOffsetPixels(mOffsetPixels * -1);
|
|
|
- }
|
|
|
-
|
|
|
- if (mSlideDrawable != null) mSlideDrawable.setIsRtl(layoutDirection == LAYOUT_DIRECTION_RTL);
|
|
|
-
|
|
|
- requestLayout();
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the number of pixels the content should be offset.
|
|
|
- *
|
|
|
- * @param offsetPixels The number of pixels to offset the content by.
|
|
|
- */
|
|
|
- protected void setOffsetPixels(float offsetPixels) {
|
|
|
- final int oldOffset = (int) mOffsetPixels;
|
|
|
- final int newOffset = (int) offsetPixels;
|
|
|
-
|
|
|
- mOffsetPixels = offsetPixels;
|
|
|
-
|
|
|
- if (mSlideDrawable != null) {
|
|
|
- final float offset = Math.abs(mOffsetPixels) / mMenuSize;
|
|
|
- mSlideDrawable.setOffset(offset);
|
|
|
- updateUpContentDescription();
|
|
|
- }
|
|
|
-
|
|
|
- if (newOffset != oldOffset) {
|
|
|
- onOffsetPixelsChanged(newOffset);
|
|
|
- mMenuVisible = newOffset != 0;
|
|
|
-
|
|
|
- // Notify any attached listeners of the current open ratio
|
|
|
- final float openRatio = ((float) Math.abs(newOffset)) / mMenuSize;
|
|
|
- dispatchOnDrawerSlide(openRatio, newOffset);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Called when the number of pixels the content should be offset by has changed.
|
|
|
- *
|
|
|
- * @param offsetPixels The number of pixels to offset the content by.
|
|
|
- */
|
|
|
- protected abstract void onOffsetPixelsChanged(int offsetPixels);
|
|
|
-
|
|
|
- /**
|
|
|
- * Toggles the menu open and close with animation.
|
|
|
- */
|
|
|
- public void toggleMenu() {
|
|
|
- toggleMenu(true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Toggles the menu open and close.
|
|
|
- *
|
|
|
- * @param animate Whether open/close should be animated.
|
|
|
- */
|
|
|
- public abstract void toggleMenu(boolean animate);
|
|
|
-
|
|
|
- /**
|
|
|
- * Animates the menu open.
|
|
|
- */
|
|
|
- public void openMenu() {
|
|
|
- openMenu(true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Opens the menu.
|
|
|
- *
|
|
|
- * @param animate Whether open/close should be animated.
|
|
|
- */
|
|
|
- public abstract void openMenu(boolean animate);
|
|
|
-
|
|
|
- /**
|
|
|
- * Animates the menu closed.
|
|
|
- */
|
|
|
- public void closeMenu() {
|
|
|
- closeMenu(true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Closes the menu.
|
|
|
- *
|
|
|
- * @param animate Whether open/close should be animated.
|
|
|
- */
|
|
|
- public abstract void closeMenu(boolean animate);
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether the menu is currently visible.
|
|
|
- *
|
|
|
- * @return True if the menu is open, false otherwise.
|
|
|
- */
|
|
|
- public abstract boolean isMenuVisible();
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the size of the menu drawer when open.
|
|
|
- *
|
|
|
- * @param size The size of the menu.
|
|
|
- */
|
|
|
- public abstract void setMenuSize(int size);
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the size of the menu.
|
|
|
- *
|
|
|
- * @return The size of the menu.
|
|
|
- */
|
|
|
- public int getMenuSize() {
|
|
|
- return mMenuSize;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the active view.
|
|
|
- * If the mdActiveIndicator attribute is set, this View will have the indicator drawn next to it.
|
|
|
- *
|
|
|
- * @param v The active view.
|
|
|
- */
|
|
|
- public void setActiveView(View v) {
|
|
|
- setActiveView(v, 0);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the active view.
|
|
|
- * If the mdActiveIndicator attribute is set, this View will have the indicator drawn next to it.
|
|
|
- *
|
|
|
- * @param v The active view.
|
|
|
- * @param position Optional position, usually used with ListView. v.setTag(R.id.mdActiveViewPosition, position)
|
|
|
- * must be called first.
|
|
|
- */
|
|
|
- public void setActiveView(View v, int position) {
|
|
|
- final View oldView = mActiveView;
|
|
|
- mActiveView = v;
|
|
|
- mActivePosition = position;
|
|
|
-
|
|
|
- if (mAllowIndicatorAnimation && oldView != null) {
|
|
|
- startAnimatingIndicator();
|
|
|
- }
|
|
|
-
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets whether the indicator should be animated between active views.
|
|
|
- *
|
|
|
- * @param animate Whether the indicator should be animated between active views.
|
|
|
- */
|
|
|
- public void setAllowIndicatorAnimation(boolean animate) {
|
|
|
- if (animate != mAllowIndicatorAnimation) {
|
|
|
- mAllowIndicatorAnimation = animate;
|
|
|
- completeAnimatingIndicator();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether the indicator should be animated between active views.
|
|
|
- *
|
|
|
- * @return Whether the indicator should be animated between active views.
|
|
|
- */
|
|
|
- public boolean getAllowIndicatorAnimation() {
|
|
|
- return mAllowIndicatorAnimation;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Scroll listener that checks whether the active view has moved before the drawer is invalidated.
|
|
|
- */
|
|
|
- private ViewTreeObserver.OnScrollChangedListener mScrollListener = new ViewTreeObserver.OnScrollChangedListener() {
|
|
|
- @Override
|
|
|
- public void onScrollChanged() {
|
|
|
- if (mActiveView != null && isViewDescendant(mActiveView)) {
|
|
|
- mActiveView.getDrawingRect(mTempRect);
|
|
|
- offsetDescendantRectToMyCoords(mActiveView, mTempRect);
|
|
|
- if (mTempRect.left != mActiveRect.left || mTempRect.top != mActiveRect.top
|
|
|
- || mTempRect.right != mActiveRect.right || mTempRect.bottom != mActiveRect.bottom) {
|
|
|
- invalidate();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- /**
|
|
|
- * Starts animating the indicator to a new position.
|
|
|
- */
|
|
|
- private void startAnimatingIndicator() {
|
|
|
- mIndicatorStartPos = getIndicatorStartPos();
|
|
|
- mIndicatorAnimating = true;
|
|
|
- mIndicatorScroller.startScroll(0.0f, 1.0f, INDICATOR_ANIM_DURATION);
|
|
|
-
|
|
|
- animateIndicatorInvalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the start position of the indicator.
|
|
|
- *
|
|
|
- * @return The start position of the indicator.
|
|
|
- */
|
|
|
- private int getIndicatorStartPos() {
|
|
|
- switch (getPosition()) {
|
|
|
- case TOP:
|
|
|
- return mIndicatorClipRect.left;
|
|
|
- case RIGHT:
|
|
|
- return mIndicatorClipRect.top;
|
|
|
- case BOTTOM:
|
|
|
- return mIndicatorClipRect.left;
|
|
|
- default:
|
|
|
- return mIndicatorClipRect.top;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Compute the touch area based on the touch mode.
|
|
|
- */
|
|
|
- protected void updateTouchAreaSize() {
|
|
|
- if (mTouchMode == TOUCH_MODE_BEZEL) {
|
|
|
- mTouchSize = mTouchBezelSize;
|
|
|
- } else if (mTouchMode == TOUCH_MODE_FULLSCREEN) {
|
|
|
- mTouchSize = getMeasuredWidth();
|
|
|
- } else {
|
|
|
- mTouchSize = 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Callback when each frame in the indicator animation should be drawn.
|
|
|
- */
|
|
|
- private void animateIndicatorInvalidate() {
|
|
|
- if (mIndicatorScroller.computeScrollOffset()) {
|
|
|
- mIndicatorOffset = mIndicatorScroller.getCurr();
|
|
|
- invalidate();
|
|
|
-
|
|
|
- if (!mIndicatorScroller.isFinished()) {
|
|
|
- postOnAnimation(mIndicatorRunnable);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- completeAnimatingIndicator();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Called when the indicator animation has completed.
|
|
|
- */
|
|
|
- private void completeAnimatingIndicator() {
|
|
|
- mIndicatorOffset = 1.0f;
|
|
|
- mIndicatorAnimating = false;
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Enables or disables offsetting the menu when dragging the drawer.
|
|
|
- *
|
|
|
- * @param offsetMenu True to offset the menu, false otherwise.
|
|
|
- */
|
|
|
- public abstract void setOffsetMenuEnabled(boolean offsetMenu);
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether the menu is being offset when dragging the drawer.
|
|
|
- *
|
|
|
- * @return True if the menu is being offset, false otherwise.
|
|
|
- */
|
|
|
- public abstract boolean getOffsetMenuEnabled();
|
|
|
-
|
|
|
- /**
|
|
|
- * Get the current state of the drawer.
|
|
|
- *
|
|
|
- * @return The state of the drawer.
|
|
|
- */
|
|
|
- public int getDrawerState() {
|
|
|
- return mDrawerState;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Register a callback to be invoked when the drawer state changes.
|
|
|
- *
|
|
|
- * @param listener The callback that will run.
|
|
|
- */
|
|
|
- public void setOnDrawerStateChangeListener(OnDrawerStateChangeListener listener) {
|
|
|
- mOnDrawerStateChangeListener = listener;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Register a callback that will be invoked when the drawer is about to intercept touch events.
|
|
|
- *
|
|
|
- * @param listener The callback that will be invoked.
|
|
|
- */
|
|
|
- public void setOnInterceptMoveEventListener(OnInterceptMoveEventListener listener) {
|
|
|
- mOnInterceptMoveEventListener = listener;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Defines whether the drop shadow is enabled.
|
|
|
- *
|
|
|
- * @param enabled Whether the drop shadow is enabled.
|
|
|
- */
|
|
|
- public void setDropShadowEnabled(boolean enabled) {
|
|
|
- mDropShadowEnabled = enabled;
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- protected GradientDrawable.Orientation getDropShadowOrientation() {
|
|
|
- // Gets the orientation for the static and sliding drawer. The overlay drawer provides its own implementation.
|
|
|
- switch (getPosition()) {
|
|
|
- case TOP:
|
|
|
- return GradientDrawable.Orientation.BOTTOM_TOP;
|
|
|
-
|
|
|
- case RIGHT:
|
|
|
- return GradientDrawable.Orientation.LEFT_RIGHT;
|
|
|
-
|
|
|
- case BOTTOM:
|
|
|
- return GradientDrawable.Orientation.TOP_BOTTOM;
|
|
|
-
|
|
|
- default:
|
|
|
- return GradientDrawable.Orientation.RIGHT_LEFT;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the color of the drop shadow.
|
|
|
- *
|
|
|
- * @param color The color of the drop shadow.
|
|
|
- */
|
|
|
- public void setDropShadowColor(int color) {
|
|
|
- GradientDrawable.Orientation orientation = getDropShadowOrientation();
|
|
|
-
|
|
|
- final int endColor = color & 0x00FFFFFF;
|
|
|
- mDropShadowDrawable = new GradientDrawable(orientation,
|
|
|
- new int[] {
|
|
|
- color,
|
|
|
- endColor,
|
|
|
- });
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the drawable of the drop shadow.
|
|
|
- *
|
|
|
- * @param drawable The drawable of the drop shadow.
|
|
|
- */
|
|
|
- public void setDropShadow(Drawable drawable) {
|
|
|
- mDropShadowDrawable = drawable;
|
|
|
- mCustomDropShadow = drawable != null;
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the drawable of the drop shadow.
|
|
|
- *
|
|
|
- * @param resId The resource identifier of the the drawable.
|
|
|
- */
|
|
|
- public void setDropShadow(int resId) {
|
|
|
- setDropShadow(getResources().getDrawable(resId));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the drawable of the drop shadow.
|
|
|
- */
|
|
|
- public Drawable getDropShadow() {
|
|
|
- return mDropShadowDrawable;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the size of the drop shadow.
|
|
|
- *
|
|
|
- * @param size The size of the drop shadow in px.
|
|
|
- */
|
|
|
- public void setDropShadowSize(int size) {
|
|
|
- mDropShadowSize = size;
|
|
|
- invalidate();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Animates the drawer slightly open until the user opens the drawer.
|
|
|
- */
|
|
|
- public abstract void peekDrawer();
|
|
|
-
|
|
|
- /**
|
|
|
- * Animates the drawer slightly open. If delay is larger than 0, this happens until the user opens the drawer.
|
|
|
- *
|
|
|
- * @param delay The delay (in milliseconds) between each run of the animation. If 0, this animation is only run
|
|
|
- * once.
|
|
|
- */
|
|
|
- public abstract void peekDrawer(long delay);
|
|
|
-
|
|
|
- /**
|
|
|
- * Animates the drawer slightly open. If delay is larger than 0, this happens until the user opens the drawer.
|
|
|
- *
|
|
|
- * @param startDelay The delay (in milliseconds) until the animation is first run.
|
|
|
- * @param delay The delay (in milliseconds) between each run of the animation. If 0, this animation is only run
|
|
|
- * once.
|
|
|
- */
|
|
|
- public abstract void peekDrawer(long startDelay, long delay);
|
|
|
-
|
|
|
- /**
|
|
|
- * Enables or disables the user of {@link View#LAYER_TYPE_HARDWARE} when animations views.
|
|
|
- *
|
|
|
- * @param enabled Whether hardware layers are enabled.
|
|
|
- */
|
|
|
- public abstract void setHardwareLayerEnabled(boolean enabled);
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the maximum duration of open/close animations.
|
|
|
- *
|
|
|
- * @param duration The maximum duration in milliseconds.
|
|
|
- */
|
|
|
- public void setMaxAnimationDuration(int duration) {
|
|
|
- mMaxAnimationDuration = duration;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets whether an overlay should be drawn when sliding the drawer.
|
|
|
- *
|
|
|
- * @param drawOverlay Whether an overlay should be drawn when sliding the drawer.
|
|
|
- */
|
|
|
- public void setDrawOverlay(boolean drawOverlay) {
|
|
|
- mDrawOverlay = drawOverlay;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Gets whether an overlay is drawn when sliding the drawer.
|
|
|
- *
|
|
|
- * @return Whether an overlay is drawn when sliding the drawer.
|
|
|
- */
|
|
|
- public boolean getDrawOverlay() {
|
|
|
- return mDrawOverlay;
|
|
|
- }
|
|
|
-
|
|
|
- protected void updateUpContentDescription() {
|
|
|
- final int upContentDesc = isMenuVisible() ? mDrawerOpenContentDesc : mDrawerClosedContentDesc;
|
|
|
- if (mDrawerIndicatorEnabled && mActionBarHelper != null && upContentDesc != mCurrentUpContentDesc) {
|
|
|
- mCurrentUpContentDesc = upContentDesc;
|
|
|
- mActionBarHelper.setActionBarDescription(upContentDesc);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the drawable used as the drawer indicator.
|
|
|
- *
|
|
|
- * @param drawable The drawable used as the drawer indicator.
|
|
|
- */
|
|
|
- public void setSlideDrawable(int drawableRes) {
|
|
|
- setSlideDrawable(getResources().getDrawable(drawableRes));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the drawable used as the drawer indicator.
|
|
|
- *
|
|
|
- * @param drawable The drawable used as the drawer indicator.
|
|
|
- */
|
|
|
- public void setSlideDrawable(Drawable drawable) {
|
|
|
- mSlideDrawable = new SlideDrawable(drawable);
|
|
|
- mSlideDrawable.setIsRtl(ViewHelper.getLayoutDirection(this) == LAYOUT_DIRECTION_RTL);
|
|
|
-
|
|
|
- if (mActionBarHelper != null) {
|
|
|
- mActionBarHelper.setDisplayShowHomeAsUpEnabled(true);
|
|
|
-
|
|
|
- if (mDrawerIndicatorEnabled) {
|
|
|
- mActionBarHelper.setActionBarUpIndicator(mSlideDrawable,
|
|
|
- isMenuVisible() ? mDrawerOpenContentDesc : mDrawerClosedContentDesc);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets up the drawer indicator. It cna then be shown with {@link #setDrawerIndicatorEnabled(boolean)}.
|
|
|
- *
|
|
|
- * @param activity The activity the drawer is attached to.
|
|
|
- */
|
|
|
- public void setupUpIndicator(Activity activity) {
|
|
|
- if (mActionBarHelper == null) {
|
|
|
- mActionBarHelper = new ActionBarHelper(activity);
|
|
|
- mThemeUpIndicator = mActionBarHelper.getThemeUpIndicator();
|
|
|
-
|
|
|
- if (mDrawerIndicatorEnabled) {
|
|
|
- mActionBarHelper.setActionBarUpIndicator(mSlideDrawable,
|
|
|
- isMenuVisible() ? mDrawerOpenContentDesc : mDrawerClosedContentDesc);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets whether the drawer indicator should be enabled. {@link #setupUpIndicator(Activity)} must be
|
|
|
- * called first.
|
|
|
- *
|
|
|
- * @param enabled Whether the drawer indicator should enabled.
|
|
|
- */
|
|
|
- public void setDrawerIndicatorEnabled(boolean enabled) {
|
|
|
- if (mActionBarHelper == null) {
|
|
|
- throw new IllegalStateException("setupUpIndicator(Activity) has not been called");
|
|
|
- }
|
|
|
-
|
|
|
- mDrawerIndicatorEnabled = enabled;
|
|
|
- if (enabled) {
|
|
|
- mActionBarHelper.setActionBarUpIndicator(mSlideDrawable,
|
|
|
- isMenuVisible() ? mDrawerOpenContentDesc : mDrawerClosedContentDesc);
|
|
|
- } else {
|
|
|
- mActionBarHelper.setActionBarUpIndicator(mThemeUpIndicator, 0);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Indicates whether the drawer indicator is currently enabled.
|
|
|
- *
|
|
|
- * @return Whether the drawer indicator is enabled.
|
|
|
- */
|
|
|
- public boolean isDrawerIndicatorEnabled() {
|
|
|
- return mDrawerIndicatorEnabled;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the ViewGroup used as a parent for the menu view.
|
|
|
- *
|
|
|
- * @return The menu view's parent.
|
|
|
- */
|
|
|
- public ViewGroup getMenuContainer() {
|
|
|
- return mMenuContainer;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the ViewGroup used as a parent for the content view.
|
|
|
- *
|
|
|
- * @return The content view's parent.
|
|
|
- */
|
|
|
- public ViewGroup getContentContainer() {
|
|
|
- if (mDragMode == MENU_DRAG_CONTENT) {
|
|
|
- return mContentContainer;
|
|
|
- } else {
|
|
|
- return (ViewGroup) findViewById(android.R.id.content);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the menu view from a layout resource.
|
|
|
- *
|
|
|
- * @param layoutResId Resource ID to be inflated.
|
|
|
- */
|
|
|
- public void setMenuView(int layoutResId) {
|
|
|
- mMenuContainer.removeAllViews();
|
|
|
- mMenuView = LayoutInflater.from(getContext()).inflate(layoutResId, mMenuContainer, false);
|
|
|
- mMenuContainer.addView(mMenuView);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the menu view to an explicit view.
|
|
|
- *
|
|
|
- * @param view The menu view.
|
|
|
- */
|
|
|
- public void setMenuView(View view) {
|
|
|
- setMenuView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the menu view to an explicit view.
|
|
|
- *
|
|
|
- * @param view The menu view.
|
|
|
- * @param params Layout parameters for the view.
|
|
|
- */
|
|
|
- public void setMenuView(View view, LayoutParams params) {
|
|
|
- mMenuView = view;
|
|
|
- mMenuContainer.removeAllViews();
|
|
|
- mMenuContainer.addView(view, params);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the menu view.
|
|
|
- *
|
|
|
- * @return The menu view.
|
|
|
- */
|
|
|
- public View getMenuView() {
|
|
|
- return mMenuView;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the content from a layout resource.
|
|
|
- *
|
|
|
- * @param layoutResId Resource ID to be inflated.
|
|
|
- */
|
|
|
- public void setContentView(int layoutResId) {
|
|
|
- switch (mDragMode) {
|
|
|
- case MenuDrawer.MENU_DRAG_CONTENT:
|
|
|
- mContentContainer.removeAllViews();
|
|
|
- LayoutInflater.from(getContext()).inflate(layoutResId, mContentContainer, true);
|
|
|
- break;
|
|
|
-
|
|
|
- case MenuDrawer.MENU_DRAG_WINDOW:
|
|
|
- mActivity.setContentView(layoutResId);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the content to an explicit view.
|
|
|
- *
|
|
|
- * @param view The desired content to display.
|
|
|
- */
|
|
|
- public void setContentView(View view) {
|
|
|
- setContentView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set the content to an explicit view.
|
|
|
- *
|
|
|
- * @param view The desired content to display.
|
|
|
- * @param params Layout parameters for the view.
|
|
|
- */
|
|
|
- public void setContentView(View view, LayoutParams params) {
|
|
|
- switch (mDragMode) {
|
|
|
- case MenuDrawer.MENU_DRAG_CONTENT:
|
|
|
- mContentContainer.removeAllViews();
|
|
|
- mContentContainer.addView(view, params);
|
|
|
- break;
|
|
|
-
|
|
|
- case MenuDrawer.MENU_DRAG_WINDOW:
|
|
|
- mActivity.setContentView(view, params);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected void setDrawerState(int state) {
|
|
|
- if (state != mDrawerState) {
|
|
|
- final int oldState = mDrawerState;
|
|
|
- mDrawerState = state;
|
|
|
- if (mOnDrawerStateChangeListener != null) mOnDrawerStateChangeListener.onDrawerStateChange(oldState, state);
|
|
|
- if (DEBUG) logDrawerState(state);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected void logDrawerState(int state) {
|
|
|
- switch (state) {
|
|
|
- case STATE_CLOSED:
|
|
|
- Log.d(TAG, "[DrawerState] STATE_CLOSED");
|
|
|
- break;
|
|
|
-
|
|
|
- case STATE_CLOSING:
|
|
|
- Log.d(TAG, "[DrawerState] STATE_CLOSING");
|
|
|
- break;
|
|
|
-
|
|
|
- case STATE_DRAGGING:
|
|
|
- Log.d(TAG, "[DrawerState] STATE_DRAGGING");
|
|
|
- break;
|
|
|
-
|
|
|
- case STATE_OPENING:
|
|
|
- Log.d(TAG, "[DrawerState] STATE_OPENING");
|
|
|
- break;
|
|
|
-
|
|
|
- case STATE_OPEN:
|
|
|
- Log.d(TAG, "[DrawerState] STATE_OPEN");
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- Log.d(TAG, "[DrawerState] Unknown: " + state);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the touch mode.
|
|
|
- */
|
|
|
- public abstract int getTouchMode();
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the drawer touch mode. Possible values are {@link #TOUCH_MODE_NONE}, {@link #TOUCH_MODE_BEZEL} or
|
|
|
- * {@link #TOUCH_MODE_FULLSCREEN}.
|
|
|
- *
|
|
|
- * @param mode The touch mode.
|
|
|
- */
|
|
|
- public abstract void setTouchMode(int mode);
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the size of the touch bezel.
|
|
|
- *
|
|
|
- * @param size The touch bezel size in px.
|
|
|
- */
|
|
|
- public abstract void setTouchBezelSize(int size);
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the size of the touch bezel in px.
|
|
|
- */
|
|
|
- public abstract int getTouchBezelSize();
|
|
|
-
|
|
|
- @Override
|
|
|
- public void postOnAnimation(Runnable action) {
|
|
|
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
|
|
- super.postOnAnimation(action);
|
|
|
- } else {
|
|
|
- postDelayed(action, ANIMATION_DELAY);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected boolean fitSystemWindows(Rect insets) {
|
|
|
- if (mDragMode == MENU_DRAG_WINDOW && mPosition != Position.BOTTOM) {
|
|
|
- mMenuContainer.setPadding(0, insets.top, 0, 0);
|
|
|
- }
|
|
|
- return super.fitSystemWindows(insets);
|
|
|
- }
|
|
|
-
|
|
|
- protected void dispatchOnDrawerSlide(float openRatio, int offsetPixels) {
|
|
|
- if (mOnDrawerStateChangeListener != null) {
|
|
|
- mOnDrawerStateChangeListener.onDrawerSlide(openRatio, offsetPixels);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Saves the state of the drawer.
|
|
|
- *
|
|
|
- * @return Returns a Parcelable containing the drawer state.
|
|
|
- */
|
|
|
- public final Parcelable saveState() {
|
|
|
- if (mState == null) mState = new Bundle();
|
|
|
- saveState(mState);
|
|
|
- return mState;
|
|
|
- }
|
|
|
-
|
|
|
- void saveState(Bundle state) {
|
|
|
- // State saving isn't required for subclasses.
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Restores the state of the drawer.
|
|
|
- *
|
|
|
- * @param in A parcelable containing the drawer state.
|
|
|
- */
|
|
|
- public void restoreState(Parcelable in) {
|
|
|
- mState = (Bundle) in;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected Parcelable onSaveInstanceState() {
|
|
|
- Parcelable superState = super.onSaveInstanceState();
|
|
|
- SavedState state = new SavedState(superState);
|
|
|
-
|
|
|
- if (mState == null) mState = new Bundle();
|
|
|
- saveState(mState);
|
|
|
-
|
|
|
- state.mState = mState;
|
|
|
- return state;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onRestoreInstanceState(Parcelable state) {
|
|
|
- SavedState savedState = (SavedState) state;
|
|
|
- super.onRestoreInstanceState(savedState.getSuperState());
|
|
|
-
|
|
|
- restoreState(savedState.mState);
|
|
|
- }
|
|
|
-
|
|
|
- static class SavedState extends BaseSavedState {
|
|
|
-
|
|
|
- Bundle mState;
|
|
|
-
|
|
|
- public SavedState(Parcelable superState) {
|
|
|
- super(superState);
|
|
|
- }
|
|
|
-
|
|
|
- public SavedState(Parcel in) {
|
|
|
- super(in);
|
|
|
- mState = in.readBundle();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void writeToParcel(Parcel dest, int flags) {
|
|
|
- super.writeToParcel(dest, flags);
|
|
|
- dest.writeBundle(mState);
|
|
|
- }
|
|
|
-
|
|
|
- @SuppressWarnings("UnusedDeclaration")
|
|
|
- public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
|
|
|
- @Override
|
|
|
- public SavedState createFromParcel(Parcel in) {
|
|
|
- return new SavedState(in);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public SavedState[] newArray(int size) {
|
|
|
- return new SavedState[size];
|
|
|
- }
|
|
|
- };
|
|
|
- }
|
|
|
-}
|