diff --git a/library/src/main/java/com/github/clans/fab/FloatingActionMenu.java b/library/src/main/java/com/github/clans/fab/FloatingActionMenu.java index 0b80e4c..e9d82ec 100755 --- a/library/src/main/java/com/github/clans/fab/FloatingActionMenu.java +++ b/library/src/main/java/com/github/clans/fab/FloatingActionMenu.java @@ -1,12 +1,17 @@ package com.github.clans.fab; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; +import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Handler; @@ -14,7 +19,6 @@ import android.util.AttributeSet; import android.util.TypedValue; import android.view.ContextThemeWrapper; -import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -75,7 +79,11 @@ public class FloatingActionMenu extends ViewGroup { private int mMenuColorNormal; private int mMenuColorPressed; private int mMenuColorRipple; + private int mFabOpenedColorNormal; + private int mFabOpenedColorPressed; + private int mFabOpenedColorRipple; private Drawable mIcon; + private int mFabOpenedIconColor; private int mAnimationDelayPerItem; private Interpolator mOpenInterpolator; private Interpolator mCloseInterpolator; @@ -99,6 +107,10 @@ public class FloatingActionMenu extends ViewGroup { private ValueAnimator mShowBackgroundAnimator; private ValueAnimator mHideBackgroundAnimator; + private ValueAnimator mFabOpenColorAnimator; + private ValueAnimator mFabCloseColorAnimator; + private ValueAnimator mFabIconOpenColorAnimator; + private ValueAnimator mFabIconCloseColorAnimator; private int mBackgroundColor; private int mLabelsPosition; @@ -160,6 +172,10 @@ private void init(Context context, AttributeSet attrs) { if (mIcon == null) { mIcon = getResources().getDrawable(R.drawable.fab_add); } + mFabOpenedColorNormal = attr.getColor(R.styleable.FloatingActionMenu_menu_opened_fab_colorNormal, Color.TRANSPARENT); + mFabOpenedColorPressed = attr.getColor(R.styleable.FloatingActionMenu_menu_opened_fab_colorPressed, Color.TRANSPARENT); + mFabOpenedColorRipple = attr.getColor(R.styleable.FloatingActionMenu_menu_opened_fab_colorRipple, -1); + mFabOpenedIconColor = attr.getColor(R.styleable.FloatingActionMenu_menu_opened_fab_iconColor, Color.TRANSPARENT); mLabelsSingleLine = attr.getBoolean(R.styleable.FloatingActionMenu_menu_labels_singleLine, false); mLabelsEllipsize = attr.getInt(R.styleable.FloatingActionMenu_menu_labels_ellipsize, 0); mLabelsMaxLines = attr.getInt(R.styleable.FloatingActionMenu_menu_labels_maxLines, -1); @@ -192,6 +208,7 @@ private void init(Context context, AttributeSet attrs) { initBackgroundDimAnimation(); createMenuButton(); + initColorAnimation(); initMenuButtonAnimations(attr); attr.recycle(); @@ -234,10 +251,80 @@ public void onAnimationUpdate(ValueAnimator animation) { }); } + private void initColorAnimation() { + mFabOpenColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), mMenuColorNormal, mFabOpenedColorNormal); + mFabOpenColorAnimator.setDuration(ANIMATION_DURATION); + mFabOpenColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mMenuButton.setColorNormal((Integer) animation.getAnimatedValue()); + } + }); + mFabOpenColorAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + mMenuButton.setColors( + mFabOpenedColorNormal, + mFabOpenedColorPressed == Color.TRANSPARENT ? mMenuColorPressed : mFabOpenedColorPressed, + mFabOpenedColorRipple == -1 ? mMenuColorRipple : mFabOpenedColorRipple + ); + mMenuButton.updateBackground(); +// mMenuButton.setColors(0xFFFF0000, 0xFF00FF00, 0xFF0000FF); + } + }); + + mFabCloseColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), mFabOpenedColorNormal, mMenuColorNormal); + mFabCloseColorAnimator.setDuration(ANIMATION_DURATION); + mFabCloseColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mMenuButton.setColorNormal((Integer) animation.getAnimatedValue()); + } + }); + mFabCloseColorAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); +// mMenuButton.setColors(0xFF00FF00, 0xFF0000FF, 0xFFFF0000); + mMenuButton.setColors(mMenuColorNormal, mMenuColorPressed, mMenuColorRipple); + mMenuButton.updateBackground(); + } + }); + + mFabIconOpenColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), Color.WHITE, mFabOpenedIconColor); + mFabIconOpenColorAnimator.setDuration(ANIMATION_DURATION); + mFabIconOpenColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { +// mImageToggle.setColorFilter((Integer) animation.getAnimatedValue()); + mImageToggle.setColorFilter(new PorterDuffColorFilter((Integer) animation.getAnimatedValue(), PorterDuff.Mode.SRC_ATOP)); + } + }); + + mFabIconCloseColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), mFabOpenedIconColor, Color.WHITE); + mFabIconCloseColorAnimator.setDuration(ANIMATION_DURATION); + mFabIconCloseColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mImageToggle.setColorFilter((Integer) animation.getAnimatedValue()); + } + }); + } + private boolean isBackgroundEnabled() { return mBackgroundColor != Color.TRANSPARENT; } + private boolean isFabColorChangeEnabled() { + return mFabOpenedColorNormal != mMenuColorNormal + && mFabOpenedColorNormal != Color.TRANSPARENT; + } + + private boolean isIconOpenColorEnabled() { + return mFabOpenedIconColor != Color.TRANSPARENT; + } + private void initPadding(int padding) { mLabelsPaddingTop = padding; mLabelsPaddingRight = padding; @@ -628,6 +715,14 @@ public void open(final boolean animate) { mShowBackgroundAnimator.start(); } + if (isFabColorChangeEnabled()) { + mFabOpenColorAnimator.start(); + } + + if (isIconOpenColorEnabled()) { + mFabIconOpenColorAnimator.start(); + } + if (mIconAnimated) { if (mIconToggleSet != null) { mIconToggleSet.start(); @@ -684,6 +779,14 @@ public void close(final boolean animate) { mHideBackgroundAnimator.start(); } + if (isFabColorChangeEnabled()) { + mFabCloseColorAnimator.start(); + } + + if (isIconOpenColorEnabled()) { + mFabIconCloseColorAnimator.start(); + } + if (mIconAnimated) { if (mIconToggleSet != null) { mIconToggleSet.start(); @@ -985,7 +1088,7 @@ public void addMenuButton(FloatingActionButton fab, int index) { public void removeAllMenuButtons() { close(true); - + List viewsToRemove = new ArrayList<>(); for (int i = 0; i < getChildCount(); i++) { View v = getChildAt(i); diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index a88bc79..d8cbd3c 100755 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -82,6 +82,10 @@ + + + + \ No newline at end of file diff --git a/sample/src/main/res/layout/menus_fragment.xml b/sample/src/main/res/layout/menus_fragment.xml index ee76f6a..0414dae 100644 --- a/sample/src/main/res/layout/menus_fragment.xml +++ b/sample/src/main/res/layout/menus_fragment.xml @@ -221,7 +221,11 @@ fab:menu_labels_ellipsize="end" fab:menu_labels_singleLine="true" fab:menu_backgroundColor="#ccffffff" - fab:menu_fab_label="Menu label"> + fab:menu_fab_label="Menu label" + fab:menu_opened_fab_colorNormal="@android:color/white" + fab:menu_opened_fab_colorPressed="#FEFEFE" + fab:menu_opened_fab_colorRipple="#22000000" + fab:menu_opened_fab_iconColor="#F00">