aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java')
-rw-r--r--app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java455
1 files changed, 226 insertions, 229 deletions
diff --git a/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java b/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java
index 8a5a193b..ed838914 100644
--- a/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java
+++ b/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java
@@ -37,39 +37,38 @@ import android.widget.TextView;
import com.wireguard.android.R;
public class FloatingActionsMenu extends ViewGroup {
- public static final int EXPAND_UP = 0;
public static final int EXPAND_DOWN = 1;
public static final int EXPAND_LEFT = 2;
public static final int EXPAND_RIGHT = 3;
-
+ public static final int EXPAND_UP = 0;
public static final int LABELS_ON_LEFT_SIDE = 0;
public static final int LABELS_ON_RIGHT_SIDE = 1;
-
+ private static final TimeInterpolator ALPHA_EXPAND_INTERPOLATOR = new DecelerateInterpolator();
private static final int ANIMATION_DURATION = 300;
+ private static final boolean BROKEN_LABEL_STYLE = Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.BRAND.equals("ASUS");
private static final float COLLAPSED_PLUS_ROTATION = 0f;
+ private static final TimeInterpolator COLLAPSE_INTERPOLATOR = new DecelerateInterpolator(3f);
private static final float EXPANDED_PLUS_ROTATION = 90f + 45f;
private static final TimeInterpolator EXPAND_INTERPOLATOR = new OvershootInterpolator();
- private static final TimeInterpolator COLLAPSE_INTERPOLATOR = new DecelerateInterpolator(3f);
- private static final TimeInterpolator ALPHA_EXPAND_INTERPOLATOR = new DecelerateInterpolator();
- private int mExpandDirection;
+ private final AnimatorSet mCollapseAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
+ private final AnimatorSet mExpandAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
+ private final Rect touchArea = new Rect(0, 0, 0, 0);
+ private float behaviorYTranslation;
+ @Nullable private FloatingActionButton mAddButton;
private int mButtonSpacing;
+ private int mButtonsCount;
+ private int mExpandDirection;
+ private boolean mExpanded;
private int mLabelsMargin;
+ private int mLabelsPosition;
+ private int mLabelsStyle;
private int mLabelsVerticalOffset;
- private boolean mExpanded;
- private final AnimatorSet mExpandAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
- private final AnimatorSet mCollapseAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
- @Nullable private FloatingActionButton mAddButton;
- @Nullable private RotatingDrawable mRotatingDrawable;
- private int mMaxButtonWidth;
+ @Nullable private OnFloatingActionsMenuUpdateListener mListener;
private int mMaxButtonHeight;
- private int mLabelsStyle;
- private int mLabelsPosition;
- private int mButtonsCount;
+ private int mMaxButtonWidth;
+ @Nullable private RotatingDrawable mRotatingDrawable;
@Nullable private TouchDelegateGroup mTouchDelegateGroup;
- @Nullable private OnFloatingActionsMenuUpdateListener mListener;
- private final Rect touchArea = new Rect(0, 0, 0, 0);
private float scrollYTranslation;
- private float behaviorYTranslation;
public FloatingActionsMenu(final Context context) {
this(context, null);
@@ -85,51 +84,39 @@ public class FloatingActionsMenu extends ViewGroup {
init(context, attrs);
}
- private void init(final Context context, @Nullable final AttributeSet attributeSet) {
- mButtonSpacing = (int) (getResources().getDimension(R.dimen.fab_actions_spacing));
- mLabelsMargin = getResources().getDimensionPixelSize(R.dimen.fab_labels_margin);
- mLabelsVerticalOffset = getResources().getDimensionPixelSize(R.dimen.fab_shadow_offset);
-
- mTouchDelegateGroup = new TouchDelegateGroup(this);
- setTouchDelegate(mTouchDelegateGroup);
-
- final TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.FloatingActionsMenu, 0, 0);
- mExpandDirection = attr.getInt(R.styleable.FloatingActionsMenu_fab_expandDirection, EXPAND_UP);
- mLabelsStyle = attr.getResourceId(R.styleable.FloatingActionsMenu_fab_labelStyle, 0);
- mLabelsPosition = attr.getInt(R.styleable.FloatingActionsMenu_fab_labelsPosition, LABELS_ON_LEFT_SIDE);
- attr.recycle();
-
- if (mLabelsStyle != 0 && expandsHorizontally()) {
- throw new IllegalStateException("Action labels in horizontal expand orientation is not supported.");
- }
-
- createAddButton(context);
+ private static int adjustForOvershoot(final int dimension) {
+ return dimension * 12 / 10;
}
- public float getScrollYTranslation() {
- return scrollYTranslation;
- }
+ public void addButton(final LabeledFloatingActionButton button) {
+ addView(button, mButtonsCount - 1);
+ mButtonsCount++;
- public void setScrollYTranslation(final float scrollYTranslation) {
- this.scrollYTranslation = scrollYTranslation;
- setTranslationY(behaviorYTranslation + scrollYTranslation);
+ if (mLabelsStyle != 0) {
+ createLabels();
+ }
}
- public float getBehaviorYTranslation() {
- return behaviorYTranslation;
+ public void collapse() {
+ collapse(false);
}
- public void setBehaviorYTranslation(final float behaviorYTranslation) {
- this.behaviorYTranslation = behaviorYTranslation;
- setTranslationY(behaviorYTranslation + scrollYTranslation);
- }
+ private void collapse(final boolean immediately) {
+ if (mExpanded) {
+ mExpanded = false;
+ mTouchDelegateGroup.setEnabled(false);
+ mCollapseAnimation.setDuration(immediately ? 0 : ANIMATION_DURATION);
+ mCollapseAnimation.start();
+ mExpandAnimation.cancel();
- public void setOnFloatingActionsMenuUpdateListener(final OnFloatingActionsMenuUpdateListener listener) {
- mListener = listener;
+ if (mListener != null) {
+ mListener.onMenuCollapsed();
+ }
+ }
}
- private boolean expandsHorizontally() {
- return mExpandDirection == EXPAND_LEFT || mExpandDirection == EXPAND_RIGHT;
+ public void collapseImmediately() {
+ collapse(true);
}
private void createAddButton(final Context context) {
@@ -156,85 +143,101 @@ public class FloatingActionsMenu extends ViewGroup {
mButtonsCount++;
}
- public void addButton(final LabeledFloatingActionButton button) {
- addView(button, mButtonsCount - 1);
- mButtonsCount++;
+ private void createLabels() {
+ final Context context = BROKEN_LABEL_STYLE ? getContext() : new ContextThemeWrapper(getContext(), mLabelsStyle);
- if (mLabelsStyle != 0) {
- createLabels();
+ for (int i = 0; i < mButtonsCount; i++) {
+ final FloatingActionButton button = (FloatingActionButton) getChildAt(i);
+
+ if (button instanceof LabeledFloatingActionButton) {
+ final String title = ((LabeledFloatingActionButton) button).getTitle();
+
+ final AppCompatTextView label = new AppCompatTextView(context);
+ if (!BROKEN_LABEL_STYLE)
+ label.setTextAppearance(context, mLabelsStyle);
+ label.setText(title);
+ addView(label);
+
+ button.setTag(R.id.fab_label, label);
+ }
}
}
- public void removeButton(final LabeledFloatingActionButton button) {
- removeView(button.getLabelView());
- removeView(button);
- button.setTag(R.id.fab_label, null);
- mButtonsCount--;
+ public void expand() {
+ if (!mExpanded) {
+ mExpanded = true;
+ mTouchDelegateGroup.setEnabled(true);
+ mCollapseAnimation.cancel();
+ mExpandAnimation.start();
+
+ if (mListener != null) {
+ mListener.onMenuExpanded();
+ }
+ }
+ }
+
+ private boolean expandsHorizontally() {
+ return mExpandDirection == EXPAND_LEFT || mExpandDirection == EXPAND_RIGHT;
}
@Override
- protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- measureChildren(widthMeasureSpec, heightMeasureSpec);
+ protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams(super.generateDefaultLayoutParams());
+ }
- int width = 0;
- int height = 0;
+ @Override
+ public ViewGroup.LayoutParams generateLayoutParams(final AttributeSet attrs) {
+ return new LayoutParams(super.generateLayoutParams(attrs));
+ }
- mMaxButtonWidth = 0;
- mMaxButtonHeight = 0;
- int maxLabelWidth = 0;
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(final ViewGroup.LayoutParams p) {
+ return new LayoutParams(super.generateLayoutParams(p));
+ }
- for (int i = 0; i < mButtonsCount; i++) {
- final View child = getChildAt(i);
+ public float getBehaviorYTranslation() {
+ return behaviorYTranslation;
+ }
- if (child.getVisibility() == GONE) {
- continue;
- }
+ public float getScrollYTranslation() {
+ return scrollYTranslation;
+ }
- switch (mExpandDirection) {
- case EXPAND_UP:
- case EXPAND_DOWN:
- mMaxButtonWidth = Math.max(mMaxButtonWidth, child.getMeasuredWidth());
- height += child.getMeasuredHeight();
- break;
- case EXPAND_LEFT:
- case EXPAND_RIGHT:
- width += child.getMeasuredWidth();
- mMaxButtonHeight = Math.max(mMaxButtonHeight, child.getMeasuredHeight());
- break;
- }
+ private void init(final Context context, @Nullable final AttributeSet attributeSet) {
+ mButtonSpacing = (int) (getResources().getDimension(R.dimen.fab_actions_spacing));
+ mLabelsMargin = getResources().getDimensionPixelSize(R.dimen.fab_labels_margin);
+ mLabelsVerticalOffset = getResources().getDimensionPixelSize(R.dimen.fab_shadow_offset);
- if (!expandsHorizontally()) {
- final TextView label = (TextView) child.getTag(R.id.fab_label);
- if (label != null) {
- maxLabelWidth = Math.max(maxLabelWidth, label.getMeasuredWidth());
- }
- }
- }
+ mTouchDelegateGroup = new TouchDelegateGroup(this);
+ setTouchDelegate(mTouchDelegateGroup);
- if (expandsHorizontally()) {
- height = mMaxButtonHeight;
- } else {
- width = mMaxButtonWidth + (maxLabelWidth > 0 ? maxLabelWidth + mLabelsMargin : 0);
- }
+ final TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.FloatingActionsMenu, 0, 0);
+ mExpandDirection = attr.getInt(R.styleable.FloatingActionsMenu_fab_expandDirection, EXPAND_UP);
+ mLabelsStyle = attr.getResourceId(R.styleable.FloatingActionsMenu_fab_labelStyle, 0);
+ mLabelsPosition = attr.getInt(R.styleable.FloatingActionsMenu_fab_labelsPosition, LABELS_ON_LEFT_SIDE);
+ attr.recycle();
- switch (mExpandDirection) {
- case EXPAND_UP:
- case EXPAND_DOWN:
- height += mButtonSpacing * (mButtonsCount - 1);
- height = adjustForOvershoot(height);
- break;
- case EXPAND_LEFT:
- case EXPAND_RIGHT:
- width += mButtonSpacing * (mButtonsCount - 1);
- width = adjustForOvershoot(width);
- break;
+ if (mLabelsStyle != 0 && expandsHorizontally()) {
+ throw new IllegalStateException("Action labels in horizontal expand orientation is not supported.");
}
- setMeasuredDimension(width, height);
+ createAddButton(context);
}
- private static int adjustForOvershoot(final int dimension) {
- return dimension * 12 / 10;
+ public boolean isExpanded() {
+ return mExpanded;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ bringChildToFront(mAddButton);
+ mButtonsCount = getChildCount();
+
+ if (mLabelsStyle != 0) {
+ createLabels();
+ }
}
@Override
@@ -367,99 +370,102 @@ public class FloatingActionsMenu extends ViewGroup {
}
@Override
- protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
- return new LayoutParams(super.generateDefaultLayoutParams());
- }
-
- @Override
- public ViewGroup.LayoutParams generateLayoutParams(final AttributeSet attrs) {
- return new LayoutParams(super.generateLayoutParams(attrs));
- }
-
- @Override
- protected ViewGroup.LayoutParams generateLayoutParams(final ViewGroup.LayoutParams p) {
- return new LayoutParams(super.generateLayoutParams(p));
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- bringChildToFront(mAddButton);
- mButtonsCount = getChildCount();
-
- if (mLabelsStyle != 0) {
- createLabels();
- }
- }
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ measureChildren(widthMeasureSpec, heightMeasureSpec);
- private static final boolean BROKEN_LABEL_STYLE = Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.BRAND.equals("ASUS");
+ int width = 0;
+ int height = 0;
- private void createLabels() {
- final Context context = BROKEN_LABEL_STYLE ? getContext() : new ContextThemeWrapper(getContext(), mLabelsStyle);
+ mMaxButtonWidth = 0;
+ mMaxButtonHeight = 0;
+ int maxLabelWidth = 0;
for (int i = 0; i < mButtonsCount; i++) {
- final FloatingActionButton button = (FloatingActionButton) getChildAt(i);
+ final View child = getChildAt(i);
- if (button instanceof LabeledFloatingActionButton) {
- final String title = ((LabeledFloatingActionButton) button).getTitle();
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
- final AppCompatTextView label = new AppCompatTextView(context);
- if (!BROKEN_LABEL_STYLE)
- label.setTextAppearance(context, mLabelsStyle);
- label.setText(title);
- addView(label);
+ switch (mExpandDirection) {
+ case EXPAND_UP:
+ case EXPAND_DOWN:
+ mMaxButtonWidth = Math.max(mMaxButtonWidth, child.getMeasuredWidth());
+ height += child.getMeasuredHeight();
+ break;
+ case EXPAND_LEFT:
+ case EXPAND_RIGHT:
+ width += child.getMeasuredWidth();
+ mMaxButtonHeight = Math.max(mMaxButtonHeight, child.getMeasuredHeight());
+ break;
+ }
- button.setTag(R.id.fab_label, label);
+ if (!expandsHorizontally()) {
+ final TextView label = (TextView) child.getTag(R.id.fab_label);
+ if (label != null) {
+ maxLabelWidth = Math.max(maxLabelWidth, label.getMeasuredWidth());
+ }
}
}
- }
- public void collapse() {
- collapse(false);
- }
+ if (expandsHorizontally()) {
+ height = mMaxButtonHeight;
+ } else {
+ width = mMaxButtonWidth + (maxLabelWidth > 0 ? maxLabelWidth + mLabelsMargin : 0);
+ }
- public void collapseImmediately() {
- collapse(true);
+ switch (mExpandDirection) {
+ case EXPAND_UP:
+ case EXPAND_DOWN:
+ height += mButtonSpacing * (mButtonsCount - 1);
+ height = adjustForOvershoot(height);
+ break;
+ case EXPAND_LEFT:
+ case EXPAND_RIGHT:
+ width += mButtonSpacing * (mButtonsCount - 1);
+ width = adjustForOvershoot(width);
+ break;
+ }
+
+ setMeasuredDimension(width, height);
}
- private void collapse(final boolean immediately) {
- if (mExpanded) {
- mExpanded = false;
- mTouchDelegateGroup.setEnabled(false);
- mCollapseAnimation.setDuration(immediately ? 0 : ANIMATION_DURATION);
- mCollapseAnimation.start();
- mExpandAnimation.cancel();
+ @Override
+ public void onRestoreInstanceState(final Parcelable state) {
+ if (state instanceof SavedState) {
+ final SavedState savedState = (SavedState) state;
+ mExpanded = savedState.mExpanded;
+ mTouchDelegateGroup.setEnabled(mExpanded);
- if (mListener != null) {
- mListener.onMenuCollapsed();
+ if (mRotatingDrawable != null) {
+ mRotatingDrawable.setRotation(mExpanded ? EXPANDED_PLUS_ROTATION : COLLAPSED_PLUS_ROTATION);
}
- }
- }
- public void toggle() {
- if (mExpanded) {
- collapse();
+ super.onRestoreInstanceState(savedState.getSuperState());
} else {
- expand();
+ super.onRestoreInstanceState(state);
}
}
- public void expand() {
- if (!mExpanded) {
- mExpanded = true;
- mTouchDelegateGroup.setEnabled(true);
- mCollapseAnimation.cancel();
- mExpandAnimation.start();
+ @Override
+ public Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ final SavedState savedState = new SavedState(superState);
+ savedState.mExpanded = mExpanded;
- if (mListener != null) {
- mListener.onMenuExpanded();
- }
- }
+ return savedState;
}
- public boolean isExpanded() {
- return mExpanded;
+ public void removeButton(final LabeledFloatingActionButton button) {
+ removeView(button.getLabelView());
+ removeView(button);
+ button.setTag(R.id.fab_label, null);
+ mButtonsCount--;
+ }
+
+ public void setBehaviorYTranslation(final float behaviorYTranslation) {
+ this.behaviorYTranslation = behaviorYTranslation;
+ setTranslationY(behaviorYTranslation + scrollYTranslation);
}
@Override
@@ -469,36 +475,27 @@ public class FloatingActionsMenu extends ViewGroup {
mAddButton.setEnabled(enabled);
}
- @Override
- public Parcelable onSaveInstanceState() {
- final Parcelable superState = super.onSaveInstanceState();
- final SavedState savedState = new SavedState(superState);
- savedState.mExpanded = mExpanded;
-
- return savedState;
+ public void setOnFloatingActionsMenuUpdateListener(final OnFloatingActionsMenuUpdateListener listener) {
+ mListener = listener;
}
- @Override
- public void onRestoreInstanceState(final Parcelable state) {
- if (state instanceof SavedState) {
- final SavedState savedState = (SavedState) state;
- mExpanded = savedState.mExpanded;
- mTouchDelegateGroup.setEnabled(mExpanded);
-
- if (mRotatingDrawable != null) {
- mRotatingDrawable.setRotation(mExpanded ? EXPANDED_PLUS_ROTATION : COLLAPSED_PLUS_ROTATION);
- }
+ public void setScrollYTranslation(final float scrollYTranslation) {
+ this.scrollYTranslation = scrollYTranslation;
+ setTranslationY(behaviorYTranslation + scrollYTranslation);
+ }
- super.onRestoreInstanceState(savedState.getSuperState());
+ public void toggle() {
+ if (mExpanded) {
+ collapse();
} else {
- super.onRestoreInstanceState(state);
+ expand();
}
}
public interface OnFloatingActionsMenuUpdateListener {
- void onMenuExpanded();
-
void onMenuCollapsed();
+
+ void onMenuExpanded();
}
private static class RotatingDrawable extends LayerDrawable {
@@ -508,6 +505,14 @@ public class FloatingActionsMenu extends ViewGroup {
super(new Drawable[]{drawable});
}
+ @Override
+ public void draw(final Canvas canvas) {
+ canvas.save();
+ canvas.rotate(mRotation, getBounds().centerX(), getBounds().centerY());
+ super.draw(canvas);
+ canvas.restore();
+ }
+
@SuppressWarnings("UnusedDeclaration")
public float getRotation() {
return mRotation;
@@ -519,14 +524,6 @@ public class FloatingActionsMenu extends ViewGroup {
mRotation = rotation;
invalidateSelf();
}
-
- @Override
- public void draw(final Canvas canvas) {
- canvas.save();
- canvas.rotate(mRotation, getBounds().centerX(), getBounds().centerY());
- super.draw(canvas);
- canvas.restore();
- }
}
public static class SavedState extends BaseSavedState {
@@ -562,10 +559,10 @@ public class FloatingActionsMenu extends ViewGroup {
private class LayoutParams extends ViewGroup.LayoutParams {
- private final ObjectAnimator mExpandDir = new ObjectAnimator();
- private final ObjectAnimator mExpandAlpha = new ObjectAnimator();
- private final ObjectAnimator mCollapseDir = new ObjectAnimator();
private final ObjectAnimator mCollapseAlpha = new ObjectAnimator();
+ private final ObjectAnimator mCollapseDir = new ObjectAnimator();
+ private final ObjectAnimator mExpandAlpha = new ObjectAnimator();
+ private final ObjectAnimator mExpandDir = new ObjectAnimator();
private boolean animationsSetToPlay;
LayoutParams(final ViewGroup.LayoutParams source) {
@@ -596,6 +593,20 @@ public class FloatingActionsMenu extends ViewGroup {
}
}
+ private void addLayerTypeListener(final Animator animator, final View view) {
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(final Animator animation) {
+ view.setLayerType(LAYER_TYPE_NONE, null);
+ }
+
+ @Override
+ public void onAnimationStart(final Animator animation) {
+ view.setLayerType(LAYER_TYPE_HARDWARE, null);
+ }
+ });
+ }
+
public void setAnimationsTarget(final View view) {
mCollapseAlpha.setTarget(view);
mCollapseDir.setTarget(view);
@@ -614,19 +625,5 @@ public class FloatingActionsMenu extends ViewGroup {
animationsSetToPlay = true;
}
}
-
- private void addLayerTypeListener(final Animator animator, final View view) {
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(final Animator animation) {
- view.setLayerType(LAYER_TYPE_NONE, null);
- }
-
- @Override
- public void onAnimationStart(final Animator animation) {
- view.setLayerType(LAYER_TYPE_HARDWARE, null);
- }
- });
- }
}
}