Animating Floating Action Button (slide up, down) depending on the Scroll

1

In this link there is the solution to ocular and show the fab button FloatingActionButton depending on the scroll

But I would like it when I hide and show the fab button I did it with an animation slide Up and Down:

    
asked by Webserveis 03.06.2016 в 12:44
source

3 answers

3

You can do it in two ways, using a class that extends from FloatingActionButton.Behavior and linking it with the view of Floating Action Button in XML or programming it directly in RecyclerView .

I'll show you the two ways and you choose the one you like best.

FIRST METHOD

When I looked for how to do just what you are asking, everything that appeared used the same method. They created a new java class and extended FloatingActionButton.Behavior to detect the movement of ListView or RecyclerView (what you use) and then link this same class with the view of Floating Action Button ( FAB ) of the next Form:

Class FABMove.java :

public class FABMove extends FloatingActionButton.Behavior {

    public FABMove(Context context, AttributeSet attrs) {
        super();
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);

        if (dyConsumed > 0) {
            CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
            int margin = layoutParams.bottomMargin;
            child.animate().translationY(child.getHeight() + margin).setInterpolator(new LinearInterpolator()).setDuration(1000).start();
        } else if (dyConsumed < 0) {
            child.animate().translationY(0).setInterpolator(new LinearInterpolator()).setDuration(1000).start();
        }
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }
}

And now, you just have to go to the file XML where you have declared the FAB and add a CoordinatorLayout encapsulating your RecyclerView and the FAB and to this you add the property app:layout_behavior that links to your java class:

<android.support.design.widget.CoordinatorLayout 
   xmlns:android="http://schemas.android.com/apk/res/android" 
   xmlns:app="http://schemas.android.com/apk/res-auto" 
   android:layout_width="match_parent" 
   android:layout_height="match_parent">  

   <android.support.v7.widget.RecyclerView 
      android:id="@+id/recycler_view" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"/>  

   <android.support.design.widget.FloatingActionButton
      android:id="@+id/fab"
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_margin="16dp" 
      app:layout_anchor="@+id/recycler_view" 
      app:layout_anchorGravity="bottom|end" 
      app:layout_behavior="com.victoria.fabsmove.FABMove" />

</android.support.design.widget.CoordinatorLayout>

Ready!

SECOND METHOD:

This method, for me, I see relatively simple, much more than the first because you do not have to create so many things. You simply have to add the function addOnScrollListener() to RecyclerView and overwrite the method onScrolled() to detect the movement of the list.

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy){
            if (dy > 0)
                // Puedes ocultarlo simplemente
                //fab.hide();
                // o añadir la animación deseada
                fab.animate().translationY(fab.getHeight() +
                            getResources().getDimension(R.dimen.fab_margin))
                            .setInterpolator(new LinearInterpolator())
                            .setDuration(1000); // Cambiar al tiempo deseado
            else if (dy < 0)
                //fab.show();
                 fab.animate().translationY(0)
                            .setInterpolator(new LinearInterpolator())
                            .setDuration(1000); // Cambiar al tiempo deseado

        }
    });

With this, everything would be ready. If you have any questions, notify us immediately.

Even so, the answer given by our colleague Andres Gillermo Castellanos A ( link ), because in addition you teach yourself to create menus directly in FAB and it is very interesting.

Good luck with your app!

    
answered by 03.06.2016 / 17:07
source
0

Partner, on this site link you will find the answer step by step and you can also download the example found in this git link

I hope I helped you.

    
answered by 03.06.2016 в 15:28
0

My solution using FloatingActionButton.Behavior adapting the response code @Vicky_Vicent

I add a flag to know if the animation is in progress, to avoid animation overload.

public class AboutFabScrollBehavior extends FloatingActionButton.Behavior {

    private boolean startAnimation = false;

    public AboutFabScrollBehavior(Context context, AttributeSet attributeSet) {
        super();
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, final FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {

        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);

        if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
            // User scrolled down and the FAB is currently visible -> hide the FAB
            if (!startAnimation) {
                Interpolator interpolador = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    interpolador = AnimationUtils.loadInterpolator(MyApplication.getAppContext(),
                            android.R.interpolator.fast_out_linear_in);
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {

                    child.animate()
                            //.translationYBy(0f)
                            .translationY(child.getHeight() +
                                    child.getContext().getResources().getDimension(R.dimen.fab_margin))
                            .setInterpolator(interpolador)
                            .setDuration(child.getContext().getResources().getInteger(android.R.integer.config_shortAnimTime))
                            .setListener(new AnimatorListenerAdapter() {
                                @Override
                                public void onAnimationEnd(Animator animation) {
                                    super.onAnimationEnd(animation);
                                    child.setVisibility(View.GONE);
                                    startAnimation = false;
                                }
                            })
                            .start();
                }
                startAnimation = true;
            }


        } else if (dyConsumed < 0 && child.getVisibility() == View.GONE) {
            // User scrolled up and the FAB is currently not visible -> show the FAB
            if (!startAnimation) {
                child.setVisibility(View.VISIBLE);

                Interpolator interpolador = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    interpolador = AnimationUtils.loadInterpolator(MyApplication.getAppContext(),
                            android.R.interpolator.fast_out_linear_in);
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    child.animate()
//                            .translationYBy(150f)
                            .translationY(0f)
                            .setInterpolator(interpolador)
                            .setDuration(child.getContext().getResources().getInteger(android.R.integer.config_shortAnimTime))
                            .setListener(new AnimatorListenerAdapter() {
                                @Override
                                public void onAnimationEnd(Animator animation) {
                                    super.onAnimationEnd(animation);
                                    startAnimation = false;
                                }
                            })
                            .start();
                }


                Animation animation = AnimationUtils.loadAnimation(MyApplication.getAppContext(),
                        R.anim.fade_in);
                child.startAnimation(animation);
            }
        }
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
        // Ensure we react to vertical scrolling
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
                || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
        //return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }
}
    
answered by 04.06.2016 в 15:16