📜 ⬆️ ⬇️

Animation Floating Action Button in Android



From the moment of the emergence of the Material design concept, one of the simplest elements in the implementation was the floating action button - FAB, the Floating Action Button. This element quickly gained wide popularity among developers and designers. In this post we will look at how you can animate a FAB and make it interactive. But first, let's look at how to add this element to your project.

FAB looks like a colored circle in the lower right corner of the screen. If in Android Studio to create a new project Blank Activity, then it will automatically generate a floating action button.


')
<android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_menu_help" /> 

Floating action button


FAB can be one of two sizes: 56 dp (default) or 40 dp. If you want to learn more about the principles of using FAB in the design of the application, then pay attention to the official Google guidelines .

In the most recent Android applications, FAB responds by scrolling through the list of items. It would be more logical to hide it during scrolling. This is what is meant:



To display this animation, create a recyclerView that recyclerView FAB to respond to scrolling. Today there are many libraries available that allow you to do this with a couple of lines of code. For example:

 public class FAB_Hide_on_Scroll extends FloatingActionButton.Behavior { public FAB_Hide_on_Scroll(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); //child -> Floating Action Button if (child.getVisibility() == View.VISIBLE && dyConsumed > 0) { child.hide(); } else if (child.getVisibility() == View.GONE && dyConsumed < 0) { child.show(); } } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) { return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL; } } 

Here we use the class FloatingActionButton.Behavior() , whose main task, according to official documentation, is to move the types of FloatingActionButton so that none of the Snackbar will overlap them. But in our case, this class is extended, so that we can use it to implement the desired button behavior.

What does this class do? Each time the scroll down is initialized, the onStartNestedScroll() method returns true. After this, the onNestedScroll() method displays or hides a button, depending on its current visibility. The constructor of the FloatingActionButton.Behavior() class is an important part of the described view behavior and is retrieved from the XML file.

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

Add the layout_behavior attribute to the FAB containing the package name, and at the end the class name. In other words, the attribute must specify the exact placement of the class in the project. For example:

 app:layout_behavior="com.valdio.valdioveliu.floatingactionbuttonproject.Scrolling_Floating_Action_Button.FAB_Hide_on_Scroll" 

The animation looks good, but you can make it even better. For example, so that the button goes off the screen while scrolling is more realistic behavior:



It uses the same logic as in the previous version, except for the way FAB disappears. The animation is pretty simple. The button goes down with the help of the LinearInterpolator . The distance she needs to go is equal to the height of the button plus the width of the bottom margin.

Please note that in the if expressions there are no View.VISIBLE and View.GONE , since in this case the view is not hidden, but only drifts off the screen.

 public class FAB_Float_on_Scroll extends FloatingActionButton.Behavior { public FAB_Float_on_Scroll(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); //child -> Floating Action Button if (dyConsumed > 0) { CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); int fab_bottomMargin = layoutParams.bottomMargin; child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start(); } else if (dyConsumed < 0) { child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start(); } } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) { return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL; } } 

Menu from FABs


There are many applications whose authors have created beautiful and well-functioning menus consisting of floating action buttons.



Let's do something similar. To begin, create a layout containing three small buttons. They are invisible and located at the very bottom of the layout, under the main FAB. Content fab_layout.xml :

 <FrameLayout 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.design.widget.FloatingActionButton android:id="@+id/fab_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_menu_compass" android:visibility="invisible" app:backgroundTint="@color/colorFAB" app:fabSize="mini" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_menu_myplaces" android:visibility="invisible" app:backgroundTint="@color/colorFAB" app:fabSize="mini" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_menu_share" android:visibility="invisible" app:backgroundTint="@color/colorFAB" app:fabSize="mini" /> </FrameLayout> 

This layout must be included in the activity layout under the main FAB.

 <include layout="@layout/fab_layout" /> 

Now you need to add an animation of the disappearance and appearance of each of the small buttons.

Note : here you may encounter a problem with working out pressing small buttons. When the animation finishes, the actual position of the button does not change, only the view moves. Therefore, you cannot properly handle the touch of a button. To solve this problem, you can customize the parameters of the layouts of each button, taking into account their new position, and only then perform an animation of the view movement.

You can see the animation itself at the end of this publication. The procedure for all buttons is the same, only the coordinates of the movement are different.

Menu display:

  FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fab1.getLayoutParams(); layoutParams.rightMargin += (int) (fab1.getWidth() * 1.7); layoutParams.bottomMargin += (int) (fab1.getHeight() * 0.25); fab1.setLayoutParams(layoutParams); fab1.startAnimation(show_fab_1); fab1.setClickable(true); 

fab1 moved by adding fields to the right and below in layoutParams , after which the animation is initiated.

Hiding the menu:

FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fab1.getLayoutParams ();
layoutParams.rightMargin - = (int) (fab1.getWidth () * 1.7);
layoutParams.bottomMargin - = (int) (fab1.getHeight () * 0.25);
fab1.setLayoutParams (layoutParams);
fab1.startAnimation (hide_fab_1);
fab1.setClickable (false);

The process of hiding is a reverse playback of the previous animation.

// Animate one of the small buttons
Animation show_fab_1 = AnimationUtils.loadAnimation (getApplication (), R.anim.fab1_show);
Animation hide_fab_1 = AnimationUtils.loadAnimation (getApplication (), R.anim.fab1_hide);

Now we will create in the res / anim / files folder for each of the animations. This is done simply, but if you have any difficulties, you can refer to the documentation .

Content fab1_show.xml :

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!-- Rotate --> <rotate android:duration="500" android:fromDegrees="30" android:interpolator="@android:anim/linear_interpolator" android:pivotX="50%" android:pivotY="50%" android:repeatCount="4" android:repeatMode="reverse" android:toDegrees="0"></rotate> <!--Move--> <translate android:duration="1000" android:fromXDelta="170%" android:fromYDelta="25%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade In--> <alpha android:duration="2000" android:fromAlpha="0.0" android:interpolator="@android:anim/decelerate_interpolator" android:toAlpha="1.0"></alpha> </set> 

Content fab1_hide.xml :

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"> <!--Move--> <translate android:duration="1000" android:fromXDelta="-170%" android:fromYDelta="-25%" android:interpolator="@android:anim/linear_interpolator" android:toXDelta="0%" android:toYDelta="0%"></translate> <!--Fade Out--> <alpha android:duration="2000" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.0"></alpha> </set> 

If you look at the translation tag (translate tag), which is responsible for the movement of the view, you will see that the translation coefficient (170% and 25%) corresponds to the coefficients used when adding fields and extracted to the Java code.

We repeat all the above steps for the remaining small buttons. Only displacement coefficients fab2 : fab2 - 150% and 150%, fab3 - 25% and 170%.

The result of our efforts:



This is not the end


I hope this article has helped you understand how you can animate the Floating Action Button in your project. Then you can explore the resources on animation in Android , and start creating your own kinds of animations. All the code described in this publication of the project is available on GitHub .

Source: https://habr.com/ru/post/369097/


All Articles