package net.simonvt.widget;
import net.simonvt.menudrawer.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
public class MenuDrawerManager {
private static final String STATE_LAYOUT = "net.simonvt.widget.MenuDrawerManager.layoutState";
/**
* The Activity the drawer is attached to.
*/
private final Activity mActivity;
/**
* The MenuDrawer layout.
*/
private MenuDrawer mMenuDrawer;
/**
* The container for the menu view.
*/
private ViewGroup mMenuContainer;
/**
* The container for the content view.
*/
private ViewGroup mContentContainer;
/**
* The custom menu view set by the user.
*/
private View mMenuView;
/**
* The drag mode of the drawer. Can be either {@link MenuDrawer#MENU_DRAG_CONTENT}
* or {@link MenuDrawer#MENU_DRAG_WINDOW}.
*/
private int mDragMode = MenuDrawer.MENU_DRAG_CONTENT;
/**
* Indicates whether the menu view has been attached to the Activity's layout.
*/
private boolean mMenuAttached;
/**
* The state passed to {@link #onRestoreDrawerState(Parcelable)}.
*/
private Bundle mRestoredState;
/**
* Constructor to use when creating the menu drawer.
*
* @param activity The activity the menu drawer will be attached to.
* @param dragMode The drag mode of the drawer. Can be either {@link MenuDrawer#MENU_DRAG_CONTENT}
* or {@link MenuDrawer#MENU_DRAG_WINDOW}.
*/
public MenuDrawerManager(Activity activity, int dragMode) {
this(activity, dragMode, MenuDrawer.MENU_POSITION_LEFT);
}
/**
* Constructor to use when creating the menu drawer.
*
* @param activity The activity the menu drawer will be attached to.
* @param dragMode The drag mode of the drawer. Can be either {@link MenuDrawer#MENU_DRAG_CONTENT}
* or {@link MenuDrawer#MENU_DRAG_WINDOW}.
* @param gravity Where to position the menu. Can be either {@link MenuDrawer#MENU_POSITION_LEFT} or
* {@link MenuDrawer#MENU_POSITION_RIGHT}.
*/
public MenuDrawerManager(Activity activity, int dragMode, int gravity) {
mActivity = activity;
mDragMode = dragMode;
mMenuDrawer = gravity == MenuDrawer.MENU_POSITION_RIGHT ? new RightDrawer(activity) : new LeftDrawer(activity);
mMenuDrawer.setDragMode(dragMode);
mMenuDrawer.setId(R.id.md__layout);
mMenuContainer = (ViewGroup) mMenuDrawer.findViewById(R.id.md__menu);
mContentContainer = (ViewGroup) mMenuDrawer.findViewById(R.id.md__content);
attachMenuLayout();
}
/**
* Attaches the menu drawer to the activity's layout.
*/
private void attachMenuLayout() {
if (!mMenuAttached) {
mMenuAttached = true;
switch (mDragMode) {
case MenuDrawer.MENU_DRAG_CONTENT:
attachToContent();
break;
case MenuDrawer.MENU_DRAG_WINDOW:
attachToDecor();
break;
default:
throw new RuntimeException("Unknown menu mode: " + mDragMode);
}
}
}
/**
* Attaches the menu drawer to the content view.
*/
private void attachToContent() {
/**
* Do not call mActivity#setContentView.
* E.g. if using with a ListActivity, Activity#setContentView is overridden and dispatched to
* MenuDrawerManager#setContentView, which then again calls Activity#setContentView.
*/
ViewGroup content = (ViewGroup) mActivity.findViewById(android.R.id.content);
content.removeAllViews();
content.addView(mMenuDrawer, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
/**
* Attaches the menu drawer to the window.
*/
private void attachToDecor() {
ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView();
ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
decorView.removeAllViews();
decorView.addView(mMenuDrawer, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mContentContainer.addView(decorChild, decorChild.getLayoutParams());
}
/**
* Returns the MenuDrawer layout.
*
* @return The MenuDrawer layout.
*/
public MenuDrawer getMenuDrawer() {
return mMenuDrawer;
}
/**
* Set the active view. If the mdArrowDrawable attribute is set, this View will have an arrow drawn next to it.
*
* @param v The active view.
*/
public void setActiveView(View v) {
setActiveView(v, 0);
}
/**
* Set the active view. If the mdArrowDrawable attribute is set, this View will have an arrow 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) {
mMenuDrawer.setActiveView(v, position);
}
/**
* Toggles the menu open and close.
*/
public void toggleMenu() {
mMenuDrawer.toggleMenu();
}
/**
* Toggles the menu open and close.
*
* @param animate Whether open/close should be animated.
*/
public void toggleMenu(boolean animate) {
mMenuDrawer.toggleMenu(animate);
}
/**
* Opens the menu.
*/
public void openMenu() {
mMenuDrawer.openMenu();
}
/**
* Opens the menu.
*
* @param animate Whether open/close should be animated.
*/
public void openMenu(boolean animate) {
mMenuDrawer.openMenu(animate);
}
/**
* Closes the menu.
*/
public void closeMenu() {
mMenuDrawer.closeMenu();
}
/**
* Closes the menu.
*
* @param animate Whether open/close should be animated.
*/
public void closeMenu(boolean animate) {
mMenuDrawer.closeMenu(animate);
}
/**
* Indicates whether the menu is currently visible.
*
* @return True if the menu is open, false otherwise.
*/
public boolean isMenuVisible() {
return mMenuDrawer.isMenuVisible();
}
/**
* Returns the state of the drawer. Can be one of {@link MenuDrawer#STATE_CLOSED}, {@link MenuDrawer#STATE_CLOSING},
* {@link MenuDrawer#STATE_DRAGGING}, {@link MenuDrawer#STATE_OPENING} or {@link MenuDrawer#STATE_OPEN}.
*
* @return The drawers state.
*/
public int getDrawerState() {
return mMenuDrawer.getDrawerState();
}
/**
* Set the menu view from a layout resource.
*
* @param layoutResId Resource ID to be inflated.
*/
public void setMenuView(int layoutResId) {
mMenuContainer.removeAllViews();
mMenuView = mActivity.getLayoutInflater().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 inflater = mActivity.getLayoutInflater();
inflater.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 ViewGroup.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;
}
}
/**
* Returns the views current state.
*
* @return Returns a Parcelable object containing the MenuDrawer's current state.
*/
public Parcelable onSaveDrawerState() {
Bundle state = new Bundle();
state.putParcelable(STATE_LAYOUT, mMenuDrawer.saveState());
return state;
}
/**
* Called to restore the MenuDrawer's state that has previously been generated with {@link #onSaveDrawerState()}.
*
* @param in The state that had previously been returned by {@link #onSaveDrawerState()}.
*/
public void onRestoreDrawerState(Parcelable in) {
mRestoredState = (Bundle) in;
mMenuDrawer.restoreState(mRestoredState.getParcelable(STATE_LAYOUT));
}
}