package com.github.tibolte.agendacalendarview.widgets; import android.content.Context; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; /** * Floating action button helping to scroll back to the current date. */ public class FloatingActionButton extends android.support.design.widget.FloatingActionButton { private static final int TRANSLATE_DURATION_MILLIS = 200; private boolean mVisible = true; private final Interpolator mInterpolator = new AccelerateDecelerateInterpolator(); // region Constructors public FloatingActionButton(Context context) { super(context); } public FloatingActionButton(Context context, AttributeSet attrs) { super(context, attrs); } public FloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } // endregion // region Overrides @Override public void show() { show(true); } @Override public void hide() { hide(true); } // endregion // region Public methods public void show(boolean animate) { toggle(true, animate, false); } public void hide(boolean animate) { toggle(false, animate, false); } public boolean isVisible() { return mVisible; } // endregion // region Private methods private void toggle(final boolean visible, final boolean animate, boolean force) { if (mVisible != visible || force) { mVisible = visible; int height = getHeight(); if (height == 0 && !force) { ViewTreeObserver vto = getViewTreeObserver(); if (vto.isAlive()) { vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { ViewTreeObserver currentVto = getViewTreeObserver(); if (currentVto.isAlive()) { currentVto.removeOnPreDrawListener(this); } toggle(visible, animate, true); return true; } }); return; } } int translationY = visible ? 0 : height + getMarginBottom(); if (animate) { animate().setInterpolator(mInterpolator) .setDuration(TRANSLATE_DURATION_MILLIS) .translationY(translationY); } else { setTranslationY(translationY); } } } private int getMarginBottom() { int marginBottom = 0; final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (layoutParams instanceof ViewGroup.MarginLayoutParams) { marginBottom = ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin; } return marginBottom; } // endregion }