|
@@ -1,4 +1,4 @@
|
|
|
-package com.novaapps;
|
|
|
|
|
|
|
+package com.novaapps.floatingactionmenu;
|
|
|
|
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.Animator;
|
|
|
import android.animation.AnimatorSet;
|
|
import android.animation.AnimatorSet;
|
|
@@ -27,32 +27,112 @@ import android.widget.TextView;
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * Component for a FloatingActionMenu.
|
|
|
|
|
+ *
|
|
|
* Created by charry on 2015/6/11. https://gist.github.com/douo/dfde289778a9b3b6918f and modified by Tristan Wiley
|
|
* Created by charry on 2015/6/11. https://gist.github.com/douo/dfde289778a9b3b6918f and modified by Tristan Wiley
|
|
|
*/
|
|
*/
|
|
|
public class FloatingActionMenu extends ViewGroup {
|
|
public class FloatingActionMenu extends ViewGroup {
|
|
|
|
|
|
|
|
|
|
+ //-- Properties --//
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Defines the rate of change for the open animation.
|
|
|
|
|
+ */
|
|
|
static final TimeInterpolator DEFAULT_OPEN_INTERPOLATOR = new OvershootInterpolator();
|
|
static final TimeInterpolator DEFAULT_OPEN_INTERPOLATOR = new OvershootInterpolator();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Defines the rate of change for the close animation.
|
|
|
|
|
+ */
|
|
|
static final TimeInterpolator DEFAULT_CLOSE_INTERPOLATOR = new AnticipateInterpolator();
|
|
static final TimeInterpolator DEFAULT_CLOSE_INTERPOLATOR = new AnticipateInterpolator();
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The main menu button that is always visible. Clicking this will open/close the menu.
|
|
|
|
|
+ */
|
|
|
private FloatingActionButton mMenuButton;
|
|
private FloatingActionButton mMenuButton;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The list of menu items to appear when the menu opens.
|
|
|
|
|
+ */
|
|
|
private ArrayList<FloatingActionButton> mMenuItems;
|
|
private ArrayList<FloatingActionButton> mMenuItems;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The list of labels to appear next to the menu items.
|
|
|
|
|
+ */
|
|
|
private ArrayList<TextView> mMenuItemLabels;
|
|
private ArrayList<TextView> mMenuItemLabels;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Animators to animate the appearance/disappearance of the menu items.
|
|
|
|
|
+ */
|
|
|
private ArrayList<ItemAnimator> mMenuItemAnimators;
|
|
private ArrayList<ItemAnimator> mMenuItemAnimators;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The set of animations to occur when the menu opens.
|
|
|
|
|
+ */
|
|
|
private AnimatorSet mOpenAnimatorSet = new AnimatorSet();
|
|
private AnimatorSet mOpenAnimatorSet = new AnimatorSet();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The set of animations to occur when the menu closes.
|
|
|
|
|
+ */
|
|
|
private AnimatorSet mCloseAnimatorSet = new AnimatorSet();
|
|
private AnimatorSet mCloseAnimatorSet = new AnimatorSet();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The image that will appear inside the main menu item.
|
|
|
|
|
+ */
|
|
|
private ImageView mIcon;
|
|
private ImageView mIcon;
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A flag representing the open state of the menu.
|
|
|
|
|
+ */
|
|
|
private boolean mOpen;
|
|
private boolean mOpen;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A flag representing the current animation stte of the menu.
|
|
|
|
|
+ */
|
|
|
private boolean animating;
|
|
private boolean animating;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A flag representing whether or not the menu should close if the user touches outside of the menu items.
|
|
|
|
|
+ */
|
|
|
private boolean mIsSetClosedOnTouchOutside = true;
|
|
private boolean mIsSetClosedOnTouchOutside = true;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The duration of the open/close animations.
|
|
|
|
|
+ */
|
|
|
private long duration = 300;
|
|
private long duration = 300;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A flag representing whether or not the menu appearance is a circle (true) or linear menu (false).
|
|
|
|
|
+ */
|
|
|
private boolean isCircle = false;
|
|
private boolean isCircle = false;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The radius of the circular menu (if application).
|
|
|
|
|
+ */
|
|
|
private int mRadius = 256;
|
|
private int mRadius = 256;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * If the radius of the circle is a multiple of the FB width, this is what that ratio is.
|
|
|
|
|
+ */
|
|
|
private float multipleOfFB = 0;
|
|
private float multipleOfFB = 0;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The gap between menu items.
|
|
|
|
|
+ */
|
|
|
private int mItemGap = 0;
|
|
private int mItemGap = 0;
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A click listener for the main menu item.
|
|
|
|
|
+ */
|
|
|
private OnMenuItemClickListener onMenuItemClickListener;
|
|
private OnMenuItemClickListener onMenuItemClickListener;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A listener for when the menu toggles between open and closed.
|
|
|
|
|
+ */
|
|
|
private OnMenuToggleListener onMenuToggleListener;
|
|
private OnMenuToggleListener onMenuToggleListener;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * A GestureDetector that looks for gestures outside the FAM and closes it if necessary.
|
|
|
|
|
+ */
|
|
|
GestureDetector mGestureDetector = new GestureDetector(getContext(),
|
|
GestureDetector mGestureDetector = new GestureDetector(getContext(),
|
|
|
new GestureDetector.SimpleOnGestureListener() {
|
|
new GestureDetector.SimpleOnGestureListener() {
|
|
|
|
|
|
|
@@ -66,10 +146,18 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
close();
|
|
close();
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * An OnItemClickListener that handles clicks on a menu item or one of its labels.
|
|
|
|
|
+ */
|
|
|
private OnClickListener mOnItemClickListener = new OnClickListener() {
|
|
private OnClickListener mOnItemClickListener = new OnClickListener() {
|
|
|
@Override
|
|
@Override
|
|
|
public void onClick(View v) {
|
|
public void onClick(View v) {
|
|
|
|
|
+ // If we click a menu item, call our MenuItemClickListener.
|
|
|
|
|
+ // Else - we are clicking a label, call our MenuItemClickListener.
|
|
|
|
|
+ // This is split into an if/else since we access different arrays for each.
|
|
|
if (v instanceof FloatingActionButton) {
|
|
if (v instanceof FloatingActionButton) {
|
|
|
int i = mMenuItems.indexOf(v);
|
|
int i = mMenuItems.indexOf(v);
|
|
|
if (onMenuItemClickListener != null) {
|
|
if (onMenuItemClickListener != null) {
|
|
@@ -86,6 +174,7 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ //-- Constructors --//
|
|
|
|
|
|
|
|
public FloatingActionMenu(Context context) {
|
|
public FloatingActionMenu(Context context) {
|
|
|
this(context, null, 0);
|
|
this(context, null, 0);
|
|
@@ -97,12 +186,16 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
|
|
|
|
|
public FloatingActionMenu(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
public FloatingActionMenu(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
|
super(context, attrs, defStyleAttr);
|
|
super(context, attrs, defStyleAttr);
|
|
|
|
|
+
|
|
|
|
|
+ // Default all lists to 5 items.
|
|
|
mMenuItems = new ArrayList<>(5);
|
|
mMenuItems = new ArrayList<>(5);
|
|
|
mMenuItemAnimators = new ArrayList<>(5);
|
|
mMenuItemAnimators = new ArrayList<>(5);
|
|
|
mMenuItemLabels = new ArrayList<>(5);
|
|
mMenuItemLabels = new ArrayList<>(5);
|
|
|
mIcon = new ImageView(context);
|
|
mIcon = new ImageView(context);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //-- Overriden methods --//
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
protected void onFinishInflate() {
|
|
protected void onFinishInflate() {
|
|
|
bringChildToFront(mMenuButton);
|
|
bringChildToFront(mMenuButton);
|
|
@@ -113,6 +206,9 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
@Override
|
|
@Override
|
|
|
public void addView(@NonNull View child, int index, LayoutParams params) {
|
|
public void addView(@NonNull View child, int index, LayoutParams params) {
|
|
|
super.addView(child, index, params);
|
|
super.addView(child, index, params);
|
|
|
|
|
+
|
|
|
|
|
+ // If the child count is greater than one, we are adding menu items.
|
|
|
|
|
+ // If the child count is not greater than one, we are adding the initial menu item.
|
|
|
if (getChildCount() > 1) {
|
|
if (getChildCount() > 1) {
|
|
|
if (child instanceof FloatingActionButton) {
|
|
if (child instanceof FloatingActionButton) {
|
|
|
addMenuItem((FloatingActionButton) child);
|
|
addMenuItem((FloatingActionButton) child);
|
|
@@ -132,70 +228,9 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void toggle() {
|
|
|
|
|
- if (!mOpen) {
|
|
|
|
|
- open();
|
|
|
|
|
- } else {
|
|
|
|
|
- close();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void open() {
|
|
|
|
|
- d("open");
|
|
|
|
|
- startOpenAnimator();
|
|
|
|
|
- mOpen = true;
|
|
|
|
|
- if (onMenuToggleListener != null) {
|
|
|
|
|
- onMenuToggleListener.onMenuToggle(true);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void close() {
|
|
|
|
|
- startCloseAnimator();
|
|
|
|
|
- mOpen = false;
|
|
|
|
|
- if (onMenuToggleListener != null) {
|
|
|
|
|
- onMenuToggleListener.onMenuToggle(true);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- protected void startCloseAnimator() {
|
|
|
|
|
- mCloseAnimatorSet.start();
|
|
|
|
|
- for (ItemAnimator anim : mMenuItemAnimators) {
|
|
|
|
|
- anim.startCloseAnimator();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- protected void startOpenAnimator() {
|
|
|
|
|
- mOpenAnimatorSet.start();
|
|
|
|
|
- for (ItemAnimator anim : mMenuItemAnimators) {
|
|
|
|
|
- anim.startOpenAnimator();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void addMenuItem(FloatingActionButton item) {
|
|
|
|
|
- mMenuItems.add(item);
|
|
|
|
|
- mMenuItemAnimators.add(new ItemAnimator(item));
|
|
|
|
|
-
|
|
|
|
|
- TextView button = new TextView(getContext());
|
|
|
|
|
-
|
|
|
|
|
- LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
|
|
|
|
- button.setLayoutParams(params);
|
|
|
|
|
-
|
|
|
|
|
- button.setBackgroundResource(R.drawable.rounded_corners);
|
|
|
|
|
-
|
|
|
|
|
- button.setTextColor(Color.WHITE);
|
|
|
|
|
- button.setText(item.getContentDescription());
|
|
|
|
|
-
|
|
|
|
|
- Integer paddingSize = (int)button.getTextSize() / 3;
|
|
|
|
|
-
|
|
|
|
|
- button.setPadding(paddingSize, paddingSize, paddingSize, paddingSize);
|
|
|
|
|
-
|
|
|
|
|
- addView(button);
|
|
|
|
|
- mMenuItemLabels.add(button);
|
|
|
|
|
- item.setTag(button);
|
|
|
|
|
- item.setOnClickListener(mOnItemClickListener);
|
|
|
|
|
- button.setOnClickListener(mOnItemClickListener);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Handles the measuring of the FAM, and sets the size according to the number of children.
|
|
|
|
|
+ */
|
|
|
@Override
|
|
@Override
|
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
|
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
@@ -240,6 +275,9 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
resolveSize(height, heightMeasureSpec));
|
|
resolveSize(height, heightMeasureSpec));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Handles a touch event in the ViewGroup and closes the FAM if necessary.
|
|
|
|
|
+ */
|
|
|
@Override
|
|
@Override
|
|
|
public boolean onTouchEvent(@NonNull MotionEvent event) {
|
|
public boolean onTouchEvent(@NonNull MotionEvent event) {
|
|
|
if (mIsSetClosedOnTouchOutside) {
|
|
if (mIsSetClosedOnTouchOutside) {
|
|
@@ -249,7 +287,9 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Sets the layout of the ViewGroup dependent on the number of menu items as well as menu direction.
|
|
|
|
|
+ */
|
|
|
@Override
|
|
@Override
|
|
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
|
System.out.println("onLayout:" + changed);
|
|
System.out.println("onLayout:" + changed);
|
|
@@ -335,6 +375,143 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Saves the state of the menu item as open or close to be able to handle device rotations.
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Parcelable onSaveInstanceState() {
|
|
|
|
|
+ d("onSaveInstanceState");
|
|
|
|
|
+ Bundle bundle = new Bundle();
|
|
|
|
|
+ bundle.putParcelable("instanceState", super.onSaveInstanceState());
|
|
|
|
|
+ bundle.putBoolean("mOpen", mOpen);
|
|
|
|
|
+ // ... save everything
|
|
|
|
|
+ return bundle;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Restores the state of the FAM after a rotation.
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void onRestoreInstanceState(Parcelable state) {
|
|
|
|
|
+ d("onRestoreInstanceState");
|
|
|
|
|
+ if (state instanceof Bundle) {
|
|
|
|
|
+ Bundle bundle = (Bundle) state;
|
|
|
|
|
+ mOpen = bundle.getBoolean("mOpen");
|
|
|
|
|
+ // ... load everything
|
|
|
|
|
+ state = bundle.getParcelable("instanceState");
|
|
|
|
|
+ }
|
|
|
|
|
+ super.onRestoreInstanceState(state);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected void onDetachedFromWindow() {
|
|
|
|
|
+ d("onDetachedFromWindow");
|
|
|
|
|
+ //getBackground().setAlpha(bgAlpha);//reset default alpha
|
|
|
|
|
+ super.onDetachedFromWindow();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void setBackground(Drawable background) {
|
|
|
|
|
+ if (background instanceof ColorDrawable) {
|
|
|
|
|
+ // after activity finish and relaucher , background drawable state still remain?
|
|
|
|
|
+ int bgAlpha = Color.alpha(((ColorDrawable) background).getColor());
|
|
|
|
|
+ d("bg:" + Integer.toHexString(bgAlpha));
|
|
|
|
|
+ super.setBackground(background);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ throw new IllegalArgumentException("floating only support color background");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //-- Open and close methods methods --//
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Toggles the menu between open and closed, depending on its current state.
|
|
|
|
|
+ */
|
|
|
|
|
+ public void toggle() {
|
|
|
|
|
+ if (!mOpen) {
|
|
|
|
|
+ open();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ close();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Opens the FloatingActionMenu.
|
|
|
|
|
+ */
|
|
|
|
|
+ public void open() {
|
|
|
|
|
+ d("open");
|
|
|
|
|
+ startOpenAnimator();
|
|
|
|
|
+ mOpen = true;
|
|
|
|
|
+ if (onMenuToggleListener != null) {
|
|
|
|
|
+ onMenuToggleListener.onMenuToggle(true);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Closes the FloatingActionMenu.
|
|
|
|
|
+ */
|
|
|
|
|
+ public void close() {
|
|
|
|
|
+ startCloseAnimator();
|
|
|
|
|
+ mOpen = false;
|
|
|
|
|
+ if (onMenuToggleListener != null) {
|
|
|
|
|
+ onMenuToggleListener.onMenuToggle(true);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //-- Animation methods. --//
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Initiates all of the closing animations.
|
|
|
|
|
+ */
|
|
|
|
|
+ protected void startCloseAnimator() {
|
|
|
|
|
+ mCloseAnimatorSet.start();
|
|
|
|
|
+ for (ItemAnimator anim : mMenuItemAnimators) {
|
|
|
|
|
+ anim.startCloseAnimator();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Initiating all of the opening animations.
|
|
|
|
|
+ */
|
|
|
|
|
+ protected void startOpenAnimator() {
|
|
|
|
|
+ mOpenAnimatorSet.start();
|
|
|
|
|
+ for (ItemAnimator anim : mMenuItemAnimators) {
|
|
|
|
|
+ anim.startOpenAnimator();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Adds a new menu item to the FloatingActionMenu.
|
|
|
|
|
+ * @param item The FloatingActionButton to add to the menu.
|
|
|
|
|
+ */
|
|
|
|
|
+ public void addMenuItem(FloatingActionButton item) {
|
|
|
|
|
+ mMenuItems.add(item);
|
|
|
|
|
+ mMenuItemAnimators.add(new ItemAnimator(item));
|
|
|
|
|
+
|
|
|
|
|
+ TextView button = new TextView(getContext());
|
|
|
|
|
+
|
|
|
|
|
+ LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
|
|
|
|
+ button.setLayoutParams(params);
|
|
|
|
|
+
|
|
|
|
|
+ button.setBackgroundResource(R.drawable.rounded_corners);
|
|
|
|
|
+
|
|
|
|
|
+ button.setTextColor(Color.WHITE);
|
|
|
|
|
+ button.setText(item.getContentDescription());
|
|
|
|
|
+
|
|
|
|
|
+ Integer paddingSize = (int)button.getTextSize() / 3;
|
|
|
|
|
+
|
|
|
|
|
+ button.setPadding(paddingSize, paddingSize, paddingSize, paddingSize);
|
|
|
|
|
+
|
|
|
|
|
+ addView(button);
|
|
|
|
|
+ mMenuItemLabels.add(button);
|
|
|
|
|
+ item.setTag(button);
|
|
|
|
|
+ item.setOnClickListener(mOnItemClickListener);
|
|
|
|
|
+ button.setOnClickListener(mOnItemClickListener);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Sets the default animation for the FAM icon, which is simply rotation.
|
|
|
|
|
+ */
|
|
|
private void createDefaultIconAnimation() {
|
|
private void createDefaultIconAnimation() {
|
|
|
Animator.AnimatorListener listener = new Animator.AnimatorListener() {
|
|
Animator.AnimatorListener listener = new Animator.AnimatorListener() {
|
|
|
@Override
|
|
@Override
|
|
@@ -411,80 +588,106 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
mCloseAnimatorSet.addListener(listener);
|
|
mCloseAnimatorSet.addListener(listener);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //-- Accessors --//
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Determines whether or not the menu is open.
|
|
|
|
|
+ * @return True if the menu is open, false otherwise.
|
|
|
|
|
+ */
|
|
|
public boolean isOpened() {
|
|
public boolean isOpened() {
|
|
|
return mOpen;
|
|
return mOpen;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public Parcelable onSaveInstanceState() {
|
|
|
|
|
- d("onSaveInstanceState");
|
|
|
|
|
- Bundle bundle = new Bundle();
|
|
|
|
|
- bundle.putParcelable("instanceState", super.onSaveInstanceState());
|
|
|
|
|
- bundle.putBoolean("mOpen", mOpen);
|
|
|
|
|
- // ... save everything
|
|
|
|
|
- return bundle;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Retrieves the OnMenuToggleListener that is applied to the FloatingActionMenu.
|
|
|
|
|
+ */
|
|
|
|
|
+ public OnMenuToggleListener getOnMenuToggleListener() {
|
|
|
|
|
+ return onMenuToggleListener;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public void onRestoreInstanceState(Parcelable state) {
|
|
|
|
|
- d("onRestoreInstanceState");
|
|
|
|
|
- if (state instanceof Bundle) {
|
|
|
|
|
- Bundle bundle = (Bundle) state;
|
|
|
|
|
- mOpen = bundle.getBoolean("mOpen");
|
|
|
|
|
- // ... load everything
|
|
|
|
|
- state = bundle.getParcelable("instanceState");
|
|
|
|
|
- }
|
|
|
|
|
- super.onRestoreInstanceState(state);
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Retrieves the OnMenuItemClickListener that is applied to the FloatingActionMenu.
|
|
|
|
|
+ */
|
|
|
|
|
+ public OnMenuItemClickListener getOnMenuItemClickListener() {
|
|
|
|
|
+ return onMenuItemClickListener;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- protected void onDetachedFromWindow() {
|
|
|
|
|
- d("onDetachedFromWindow");
|
|
|
|
|
- //getBackground().setAlpha(bgAlpha);//reset default alpha
|
|
|
|
|
- super.onDetachedFromWindow();
|
|
|
|
|
|
|
+ //-- Mutators --//
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Assigns an OnMenuToggleListener to the FloatingActionMenu.
|
|
|
|
|
+ */
|
|
|
|
|
+ public void setOnMenuToggleListener(OnMenuToggleListener onMenuToggleListener) {
|
|
|
|
|
+ this.onMenuToggleListener = onMenuToggleListener;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public void setBackground(Drawable background) {
|
|
|
|
|
- if (background instanceof ColorDrawable) {
|
|
|
|
|
- // after activity finish and relaucher , background drawable state still remain?
|
|
|
|
|
- int bgAlpha = Color.alpha(((ColorDrawable) background).getColor());
|
|
|
|
|
- d("bg:" + Integer.toHexString(bgAlpha));
|
|
|
|
|
- super.setBackground(background);
|
|
|
|
|
- } else {
|
|
|
|
|
- throw new IllegalArgumentException("floating only support color background");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Assigns an OnMenuItemClickListener to the FloatingActionMenu.
|
|
|
|
|
+ */
|
|
|
|
|
+ public void setOnMenuItemClickListener(OnMenuItemClickListener onMenuItemClickListener) {
|
|
|
|
|
+ this.onMenuItemClickListener = onMenuItemClickListener;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public OnMenuToggleListener getOnMenuToggleListener() {
|
|
|
|
|
- return onMenuToggleListener;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Set as circle(default) or line pattern
|
|
|
|
|
+ */
|
|
|
|
|
+ public void setIsCircle(boolean isCircle) {
|
|
|
|
|
+ this.isCircle = isCircle;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void setOnMenuToggleListener(OnMenuToggleListener onMenuToggleListener) {
|
|
|
|
|
- this.onMenuToggleListener = onMenuToggleListener;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Set the radius of menu, default 256
|
|
|
|
|
+ */
|
|
|
|
|
+ public void setmRadius(int mRadius) {
|
|
|
|
|
+ this.mRadius = mRadius;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public OnMenuItemClickListener getOnMenuItemClickListener() {
|
|
|
|
|
- return onMenuItemClickListener;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Set radius as multiple of width of floating action button
|
|
|
|
|
+ */
|
|
|
|
|
+ public void setMultipleOfFB(float multipleOfFB) {
|
|
|
|
|
+ this.multipleOfFB = multipleOfFB;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void setOnMenuItemClickListener(OnMenuItemClickListener onMenuItemClickListener) {
|
|
|
|
|
- this.onMenuItemClickListener = onMenuItemClickListener;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Duration of anim, default 300
|
|
|
|
|
+ */
|
|
|
|
|
+ public void setDuration(long duration) {
|
|
|
|
|
+ this.duration = duration;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Only usefully in Line pattern - sets the gap between menu items.
|
|
|
|
|
+ */
|
|
|
|
|
+ public void setmItemGap(int mItemGap) {
|
|
|
|
|
+ this.mItemGap = mItemGap;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //-- Misc/Helper methods --//
|
|
|
|
|
+
|
|
|
protected void d(String msg) {
|
|
protected void d(String msg) {
|
|
|
Log.d("FAM", msg == null ? null : msg);
|
|
Log.d("FAM", msg == null ? null : msg);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //-- Interfaces --//
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Interface that handles a change in the open/close state of the FloatingActionMenu.
|
|
|
|
|
+ */
|
|
|
public interface OnMenuToggleListener {
|
|
public interface OnMenuToggleListener {
|
|
|
void onMenuToggle(boolean opened);
|
|
void onMenuToggle(boolean opened);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Interface that handles the click action of a MenuItem.
|
|
|
|
|
+ */
|
|
|
public interface OnMenuItemClickListener {
|
|
public interface OnMenuItemClickListener {
|
|
|
void onMenuItemClick(FloatingActionMenu fam, int index, FloatingActionButton item);
|
|
void onMenuItemClick(FloatingActionMenu fam, int index, FloatingActionButton item);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Animator that controls the open/close animation of menu items.
|
|
|
|
|
+ */
|
|
|
private class ItemAnimator implements Animator.AnimatorListener {
|
|
private class ItemAnimator implements Animator.AnimatorListener {
|
|
|
private View mView;
|
|
private View mView;
|
|
|
private boolean playingOpenAnimator;
|
|
private boolean playingOpenAnimator;
|
|
@@ -549,44 +752,4 @@ public class FloatingActionMenu extends ViewGroup {
|
|
|
public void onAnimationRepeat(Animator animation) {
|
|
public void onAnimationRepeat(Animator animation) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * set as circle(default) or line pattern
|
|
|
|
|
- * @param isCircle
|
|
|
|
|
- */
|
|
|
|
|
- public void setIsCircle(boolean isCircle) {
|
|
|
|
|
- this.isCircle = isCircle;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * set the radius of menu, default 256
|
|
|
|
|
- * @param mRadius
|
|
|
|
|
- */
|
|
|
|
|
- public void setmRadius(int mRadius) {
|
|
|
|
|
- this.mRadius = mRadius;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * set radius as multiple of width of floating action button
|
|
|
|
|
- * @param multipleOfFB
|
|
|
|
|
- */
|
|
|
|
|
- public void setMultipleOfFB(float multipleOfFB) {
|
|
|
|
|
- this.multipleOfFB = multipleOfFB;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * duration of anim, default 300
|
|
|
|
|
- * @param duration
|
|
|
|
|
- */
|
|
|
|
|
- public void setDuration(long duration) {
|
|
|
|
|
- this.duration = duration;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Only usefully in Line pattern
|
|
|
|
|
- * @param mItemGap
|
|
|
|
|
- */
|
|
|
|
|
- public void setmItemGap(int mItemGap) {
|
|
|
|
|
- this.mItemGap = mItemGap;
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|