In an Android application that allows users on social networks to show and hide the FAB using the following code:

public abstract class LoginFragment extends Fragment { private FloatingActionButton mFab; private Animation mShowFab; private Animation mHideFab; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mShowFab = AnimationUtils.makeInAnimation(getContext(), false); mShowFab.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mFab.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } }); mHideFab = AnimationUtils.makeOutAnimation(getContext(), true); mHideFab.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mFab.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); } private void showFab(boolean show) { boolean visible = mFab.isShown(); if (show && !visible) { mFab.startAnimation(mShowFab); } else if (!show && visible) { mFab.startAnimation(mHideFab); } }
This works well when I call the showFab method above rather slow.
Before starting any animation, I check the current visibility of the FloatingActionButton so that the animation plays only once - even if I call, for example, showFab(true) several times in a row.
My problem:
When LoginFragment displayed in my application, I first send a request to ServiceIntent to retrieve user data from SQLite and the following method is called to set my user interface to standby:
private void setBusy(boolean busy) { mProgressBar.setVisibility(busy ? View.VISIBLE : View.INVISIBLE); showFab(!busy); }
Almost immediately, the response from SQLite is returned - through the LocalBroadcastManager , and I again call the method above: setBusy(false) .
And then an error occurs, and the FAB not displayed.
If I replaced the FAB method with code without animation, everything would be fine:
private void showFab(boolean show) { mFab.setVisibility(show ? View.VISIBLE : View.INVISIBLE); }
But with animation, a racing condition arises.
As a workaround, I tried to cancel both animations - but this does not help:
private void showFab(boolean show) { mShowFab.cancel(); mShowFab.reset(); mHideFab.cancel(); mHideFab.reset(); boolean visible = mFab.isShown(); if (show && !visible) { mFab.startAnimation(mShowFab); } else if (!show && visible) { mFab.startAnimation(mHideFab); } }
Please suggest what can be done here.
I have already gone through my application in the debugger many times. setBusy (and showFab ) is only called twice when a fragment is displayed, but both calls happen very quickly - and FAB not displayed -
First start:

Second run:

UPDATE:
Unfortunately, the synchronized method does not help either - the FAB remains hidden:
private synchronized void showFab(boolean show) { mShowFab.cancel(); mShowFab.reset(); mHideFab.cancel(); mHideFab.reset(); boolean visible = mFab.isShown(); if (show && !visible) { mFab.startAnimation(mShowFab); } else if (!show && visible) { mFab.startAnimation(mHideFab); } }