Skip to content

Commit

Permalink
Menu can be closed on touch to non-button area
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksandr.zaycev committed Apr 24, 2015
1 parent 0b5ca5d commit 543b3c9
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.yalantis.contextmenu.R;
import com.yalantis.contextmenu.lib.ContextMenuDialogFragment;
import com.yalantis.contextmenu.lib.MenuObject;
import com.yalantis.contextmenu.lib.MenuParams;
import com.yalantis.contextmenu.lib.interfaces.OnMenuItemClickListener;
import com.yalantis.contextmenu.lib.interfaces.OnMenuItemLongClickListener;

Expand All @@ -38,10 +39,18 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
initToolbar();
mMenuDialogFragment = ContextMenuDialogFragment.newInstance((int) getResources().getDimension(R.dimen.tool_bar_height), getMenuObjects());
initMenuFragment();
addFragment(new MainFragment(), true, R.id.container);
}

private void initMenuFragment() {
MenuParams menuParams = new MenuParams();
menuParams.setActionBarSize((int) getResources().getDimension(R.dimen.tool_bar_height));
menuParams.setMenuObjects(getMenuObjects());
menuParams.setClosableOutside(false);
mMenuDialogFragment = ContextMenuDialogFragment.newInstance(menuParams);
}

private List<MenuObject> getMenuObjects() {
// You can use any [resource, bitmap, drawable, color] as image:
// item.setResource(...)
Expand Down Expand Up @@ -143,10 +152,10 @@ public boolean onOptionsItemSelected(MenuItem item) {

@Override
public void onBackPressed() {
if (fragmentManager.getBackStackEntryCount() == 1) {
if (mMenuDialogFragment != null && mMenuDialogFragment.isAdded()) {
mMenuDialogFragment.dismiss();
} else{
finish();
} else {
super.onBackPressed();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.yalantis.contextmenu.lib;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
Expand All @@ -18,76 +19,68 @@
import com.yalantis.contextmenu.lib.interfaces.OnMenuItemClickListener;
import com.yalantis.contextmenu.lib.interfaces.OnMenuItemLongClickListener;

import java.util.ArrayList;
import java.util.List;

public class ContextMenuDialogFragment extends DialogFragment implements OnItemClickListener, OnItemLongClickListener {

public static final String TAG = ContextMenuDialogFragment.class.getSimpleName();
private static final String ACTION_BAR_SIZE = "action_bar_size";
private static final String MENU_OBJECTS = "menu_objects";
private static final String ANIMATION_DELAY = "animation_delay";
private static final String ANIMATION_DURATION = "animation_duration";
private static final String FITS_SYSTEM_WINDOW = "fits_system_window";
private static final String CLIP_TO_PADDING = "clip_to_padding";
private static final String BUNDLE_MENU_PARAMS = "BUNDLE_MENU_PARAMS";

private LinearLayout mWrapperButtons;
private LinearLayout mWrapperText;
private MenuAdapter mDropDownMenuAdapter;
private ArrayList<MenuObject> mMenuObjects;
private int mActionBarHeight;
private OnMenuItemClickListener mItemClickListener;
private OnMenuItemLongClickListener mItemLongClickListener;
/**
* Delay after opening and before closing {@link com.yalantis.contextmenu.lib.ContextMenuDialogFragment}
*/
private int mAnimationDelay = 0;
private int mAnimationDuration;
private MenuParams mMenuParams;

@Deprecated
public static ContextMenuDialogFragment newInstance(int actionBarSize, List<MenuObject> menuObjects) {
ContextMenuDialogFragment contextMenuDialogFragment = new ContextMenuDialogFragment();
Bundle args = new Bundle();
args.putInt(ACTION_BAR_SIZE, actionBarSize);
args.putParcelableArrayList(MENU_OBJECTS, new ArrayList<>(menuObjects));
contextMenuDialogFragment.setArguments(args);
return contextMenuDialogFragment;
MenuParams params = new MenuParams();
params.setActionBarSize(actionBarSize);
params.setMenuObjects(menuObjects);
return newInstance(params);
}

@Deprecated
public static ContextMenuDialogFragment newInstance(int actionBarSize, List<MenuObject> menuObjects, int animationDelay) {
ContextMenuDialogFragment contextMenuDialogFragment = new ContextMenuDialogFragment();
Bundle args = new Bundle();
args.putInt(ACTION_BAR_SIZE, actionBarSize);
args.putParcelableArrayList(MENU_OBJECTS, new ArrayList<>(menuObjects));
args.putInt(ANIMATION_DELAY, animationDelay);
contextMenuDialogFragment.setArguments(args);
return contextMenuDialogFragment;
MenuParams params = new MenuParams();
params.setActionBarSize(actionBarSize);
params.setMenuObjects(menuObjects);
params.setAnimationDelay(animationDelay);
return newInstance(params);
}

@Deprecated
public static ContextMenuDialogFragment newInstance(int actionBarSize, List<MenuObject> menuObjects, int animationDelay, int animationDuration) {
ContextMenuDialogFragment contextMenuDialogFragment = new ContextMenuDialogFragment();
Bundle args = new Bundle();
args.putInt(ACTION_BAR_SIZE, actionBarSize);
args.putParcelableArrayList(MENU_OBJECTS, new ArrayList<>(menuObjects));
args.putInt(ANIMATION_DELAY, animationDelay);
args.putInt(ANIMATION_DURATION, animationDuration);
contextMenuDialogFragment.setArguments(args);
return contextMenuDialogFragment;
MenuParams params = new MenuParams();
params.setActionBarSize(actionBarSize);
params.setMenuObjects(menuObjects);
params.setAnimationDelay(animationDelay);
params.setAnimationDuration(animationDuration);
return newInstance(params);
}

@Deprecated
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public static ContextMenuDialogFragment newInstance(int actionBarSize, List<MenuObject> menuObjects,
int animationDelay, int animationDuration,
boolean fitsSystemWindow, boolean clipToPadding) {
ContextMenuDialogFragment contextMenuDialogFragment = new ContextMenuDialogFragment();
MenuParams params = new MenuParams();
params.setActionBarSize(actionBarSize);
params.setMenuObjects(menuObjects);
params.setAnimationDelay(animationDelay);
params.setAnimationDuration(animationDuration);
params.setFitsSystemWindow(fitsSystemWindow);
params.setClipToPadding(clipToPadding);
return newInstance(params);
}

public static ContextMenuDialogFragment newInstance(MenuParams menuParams) {
ContextMenuDialogFragment fragment = new ContextMenuDialogFragment();
Bundle args = new Bundle();
args.putInt(ACTION_BAR_SIZE, actionBarSize);
args.putParcelableArrayList(MENU_OBJECTS, new ArrayList<>(menuObjects));
args.putInt(ANIMATION_DELAY, animationDelay);
args.putInt(ANIMATION_DURATION, animationDuration);
args.putBoolean(FITS_SYSTEM_WINDOW, fitsSystemWindow);
args.putBoolean(CLIP_TO_PADDING, clipToPadding);
contextMenuDialogFragment.setArguments(args);
return contextMenuDialogFragment;
args.putParcelable(BUNDLE_MENU_PARAMS, menuParams);
fragment.setArguments(args);
return fragment;
}

@Override
Expand All @@ -112,26 +105,16 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_FRAME, R.style.MenuFragmentStyle);
if (getArguments() != null) {
mActionBarHeight = getArguments().getInt(ACTION_BAR_SIZE);
mMenuObjects = getArguments().getParcelableArrayList(MENU_OBJECTS);
if(getArguments().containsKey(ANIMATION_DELAY)){
mAnimationDelay = getArguments().getInt(ANIMATION_DELAY);
}
mAnimationDuration = (getArguments().containsKey(ANIMATION_DURATION))?
getArguments().getInt(ANIMATION_DURATION): MenuAdapter.ANIMATION_DURATION_MILLIS;
mMenuParams = getArguments().getParcelable(BUNDLE_MENU_PARAMS);
}
}

@SuppressLint("NewApi")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_menu, container, false);

if (getArguments().containsKey(FITS_SYSTEM_WINDOW)) {
rootView.setFitsSystemWindows(getArguments().getBoolean(FITS_SYSTEM_WINDOW));
}
if (getArguments().containsKey(CLIP_TO_PADDING)) {
((ViewGroup) rootView).setClipToPadding(getArguments().getBoolean(CLIP_TO_PADDING));
}
rootView.setFitsSystemWindows(mMenuParams.isFitsSystemWindow());
((ViewGroup) rootView).setClipToPadding(mMenuParams.isClipToPadding());

initViews(rootView);
getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
Expand All @@ -141,7 +124,16 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
public void run() {
mDropDownMenuAdapter.menuToggle();
}
},mAnimationDelay);
}, mMenuParams.getAnimationDelay());

if (mMenuParams.isClosableOutside()) {
rootView.findViewById(R.id.root).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
}
return rootView;
}

Expand All @@ -151,10 +143,11 @@ private void initViews(View view) {
}

private void initDropDownMenuAdapter() {
mDropDownMenuAdapter = new MenuAdapter(getActivity(), mWrapperButtons, mWrapperText, mMenuObjects, mActionBarHeight);
mDropDownMenuAdapter = new MenuAdapter(getActivity(), mWrapperButtons, mWrapperText,
mMenuParams.getMenuObjects(), mMenuParams.getActionBarSize());
mDropDownMenuAdapter.setOnItemClickListener(this);
mDropDownMenuAdapter.setOnItemLongClickListener(this);
mDropDownMenuAdapter.setAnimationDuration(mAnimationDuration);
mDropDownMenuAdapter.setAnimationDuration(mMenuParams.getAnimationDuration());
}

private void close() {
Expand All @@ -163,7 +156,7 @@ private void close() {
public void run() {
dismiss();
}
},mAnimationDelay);
}, mMenuParams.getAnimationDelay());
}

/**
Expand Down
16 changes: 12 additions & 4 deletions lib/src/main/java/com/yalantis/contextmenu/lib/MenuObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,12 @@ public int describeContents() {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.mTitle);
dest.writeParcelable(((BitmapDrawable) this.mBgDrawable).getBitmap(), flags);
dest.writeParcelable(mBgDrawable == null ? null :
((BitmapDrawable) this.mBgDrawable).getBitmap(), flags);
dest.writeInt(this.mBgColor);
dest.writeInt(this.mBgResource);
dest.writeParcelable(((BitmapDrawable) this.mDrawable).getBitmap(), flags);
dest.writeParcelable(mDrawable == null ? null :
((BitmapDrawable) this.mDrawable).getBitmap(), flags);
dest.writeInt(this.mColor);
dest.writeParcelable(this.mBitmap, 0);
dest.writeInt(this.mResource);
Expand All @@ -188,10 +190,16 @@ public void writeToParcel(Parcel dest, int flags) {

private MenuObject(Parcel in) {
this.mTitle = in.readString();
this.mBgDrawable = new BitmapDrawable((Bitmap) in.readParcelable(getClass().getClassLoader()));
Bitmap bitmapBgDrawable = in.readParcelable(Bitmap.class.getClassLoader());
if (bitmapBgDrawable != null) {
this.mBgDrawable = new BitmapDrawable(bitmapBgDrawable);
}
this.mBgColor = in.readInt();
this.mBgResource = in.readInt();
this.mDrawable = new BitmapDrawable((Bitmap) in.readParcelable(Drawable.class.getClassLoader()));
Bitmap bitmapDrawable = in.readParcelable(Bitmap.class.getClassLoader());
if (bitmapDrawable != null) {
this.mDrawable = new BitmapDrawable(bitmapDrawable);
}
this.mColor = in.readInt();
this.mBitmap = in.readParcelable(Bitmap.class.getClassLoader());
this.mResource = in.readInt();
Expand Down
126 changes: 126 additions & 0 deletions lib/src/main/java/com/yalantis/contextmenu/lib/MenuParams.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.yalantis.contextmenu.lib;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.List;

/**
* Created by Aleksandr on 24.04.2015.
*/
public class MenuParams implements Parcelable {

private int mActionBarSize = 0;
private List<MenuObject> mMenuObjects;
/**
* Delay after opening and before closing {@link com.yalantis.contextmenu.lib.ContextMenuDialogFragment}
*/
private int mAnimationDelay = 0;
private int mAnimationDuration = MenuAdapter.ANIMATION_DURATION_MILLIS;
private boolean isFitsSystemWindow = false;
private boolean isClipToPadding = true;
/**
* If option menu can be closed on touch to non-button area
*/
private boolean isClosableOutside = false;

public void setActionBarSize(int mActionBarSize) {
this.mActionBarSize = mActionBarSize;
}

public void setMenuObjects(List<MenuObject> mMenuObjects) {
this.mMenuObjects = mMenuObjects;
}

public void setAnimationDelay(int mAnimationDelay) {
this.mAnimationDelay = mAnimationDelay;
}

public void setAnimationDuration(int mAnimationDuration) {
this.mAnimationDuration = mAnimationDuration;
}

public void setFitsSystemWindow(boolean mFitsSystemWindow) {
this.isFitsSystemWindow = mFitsSystemWindow;
}

public void setClipToPadding(boolean mClipToPadding) {
this.isClipToPadding = mClipToPadding;
}

/**
* Set option menu can be closed on touch to non-button area
* @param isClosableOutside true if can
*/
public void setClosableOutside(boolean isClosableOutside) {
this.isClosableOutside = isClosableOutside;
}

public int getActionBarSize() {
return mActionBarSize;
}

public List<MenuObject> getMenuObjects() {
return mMenuObjects;
}

public int getAnimationDelay() {
return mAnimationDelay;
}

public int getAnimationDuration() {
return mAnimationDuration;
}

public boolean isFitsSystemWindow() {
return isFitsSystemWindow;
}

public boolean isClipToPadding() {
return isClipToPadding;
}

public boolean isClosableOutside() {
return isClosableOutside;
}


@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mActionBarSize);
dest.writeTypedList(mMenuObjects);
dest.writeInt(this.mAnimationDelay);
dest.writeInt(this.mAnimationDuration);
dest.writeByte(isFitsSystemWindow ? (byte) 1 : (byte) 0);
dest.writeByte(isClipToPadding ? (byte) 1 : (byte) 0);
dest.writeByte(isClosableOutside ? (byte) 1 : (byte) 0);
}

public MenuParams() {
}

private MenuParams(Parcel in) {
this.mActionBarSize = in.readInt();
in.readTypedList(mMenuObjects, MenuObject.CREATOR);
this.mAnimationDelay = in.readInt();
this.mAnimationDuration = in.readInt();
this.isFitsSystemWindow = in.readByte() != 0;
this.isClipToPadding = in.readByte() != 0;
this.isClosableOutside = in.readByte() != 0;
}

public static final Parcelable.Creator<MenuParams> CREATOR = new Parcelable.Creator<MenuParams>() {
public MenuParams createFromParcel(Parcel source) {
return new MenuParams(source);
}

public MenuParams[] newArray(int size) {
return new MenuParams[size];
}
};
}
Loading

0 comments on commit 543b3c9

Please sign in to comment.