I solved my problem a few weeks ago, and I figured I should probably answer my own question here :)
After several days of research, I had found that the best way to implement this is by using the new RecyclerView introduced by Android. You can handle small pixel changes in scrolling with RecyclerView, but with ListView you would almost never be able to do that (only can handle change of "items" scrolled).
I've implemented a ScrollView Listener to my RecyclerView like this :
public abstract class HidingScrollListener extends RecyclerView.OnScrollListener {
private static final int HIDE_THRESHOLD = 20;
private int scrolledDistance = 0;
private boolean controlsVisible = true;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstVisibleItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
//show views if first item is first visible position and views are hidden
if (firstVisibleItem == 0) {
if(!controlsVisible) {
onShow();
controlsVisible = true;
}
} else {
if (scrolledDistance > HIDE_THRESHOLD && controlsVisible) {
onHide();
controlsVisible = false;
scrolledDistance = 0;
} else if (scrolledDistance < -HIDE_THRESHOLD && !controlsVisible) {
onShow();
controlsVisible = true;
scrolledDistance = 0;
}
}
if((controlsVisible && dy>0) || (!controlsVisible && dy<0)) {
scrolledDistance += dy;
}
}
public abstract void onHide();
public abstract void onShow();
This code does MORE than just show or hide FABs on scroll, it actually handles a pretty perfect "action bar disappears on scrolling" effect. But, I don't have time to suit this code to your needs, but it does work for our case, here.
To get back to our code, after creating our listener, we can add it to our FABs by implementing its interfaces :
recyclerView.setOnScrollListener(new HidingScrollListener() {
@Override
public void onHide() {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) fam.getLayoutParams();
int fabBottomMargin = lp.bottomMargin;
fam.animate().translationY(fam.getHeight()+fabBottomMargin).setInterpolator(new AccelerateInterpolator(2)).start();
}
@Override
public void onShow() {
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
fam.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();
}
});
And Voilà !