Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make the FAB avoid being moved in ViewPager, yet be a part of the fragment within?

Background

According to the material design guidelines (here), if you use a ViewPager that has a FAB (floating action button) for the fragments within, the FAB shouldn't move as a part of the fragments, but either disappear or be replaced by another, or animate to something else.

In short, instead of this:

https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0B6Okdz75tqQsNVRkV3FZMktvMWc/components-buttons-fab-behavior_06_xhdpi_009.webm

you should do this:

https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0B6Okdz75tqQsVlhxNGJCNTEzNFU/components-buttons-fab-behavior_04_xhdpi_009.webm

The problem

I don't see any example or tutorial of what's the best way to perform this.

I mean, having a FAB for each fragment (or some of them) in the ViewPager, while each will be controlled by its fragment (logic and how it looks), yet the FAB won't really move as part of the fragment while sliding between the fragments in the ViewPager.

Even as example apps, I don't see this behavior anywhere. The contacts app has the same FAB for both fragments, and the dialer has the FAB just moving.

There are even apps that use the bad behavior (like Solid-Explorer). On YouTube, there is a FAB (on the "Account" fragment), but it's on the header, so it might be ok there.

The question

How should you implement the correct behavior? Would you really put the FAB as a part of the activity instead of the fragments?

Is there maybe a tutorial and/or sample about this ?

Maybe, when the ViewPager starts scrolling, I could detach the FAB, and attach it to the activity, animate while being scrolled, and when it's done scrolling, I could hide it and show the one of the other fragment?

like image 286
android developer Avatar asked Aug 03 '15 07:08

android developer


1 Answers

I faced the same problem with a viewpager and fab little time ago and I solved in this way:

  • Attach the fab to the activity above the viewpager
  • Add OnPageChangeListener to ViewPager and save the onPageSelected(int position)'s position in a global variable in your activity
  • In onPageSelected start the anim of your fab (it can be both xml or programmatically, i did it with xml) and change his colorTint
  • In your OnClickListener's onClick(View v) when you retrieve fab id (or view) of your fab to determine which action you should perform, you can create a switch statement with the position you get before in onPageSelected

EDIT

These are my two anim.xml that i tried to create similar to android guidelines:

Anim to make disappear old fab:

<?xml version="1.0" encoding="utf-8"?>
<set android:shareInterpolator="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromXScale="1.0"
    android:toXScale="0.0"
    android:fromYScale="1.0"
    android:toYScale="0.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fillAfter="false"
    android:duration="200" />

<rotate
    android:duration="200"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromDegrees="360"
    android:toDegrees="270" />
</set>

Anim to show new one:

<?xml version="1.0" encoding="utf-8"?>
<set android:shareInterpolator="false"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromXScale="0.0"
        android:toXScale="1.0"
        android:fromYScale="0.0"
        android:toYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fillAfter="false"
        android:duration="200" />

    <rotate
        android:duration="200"
        android:interpolator="@android:anim/linear_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromDegrees="270"
        android:toDegrees="360" />
</set>
like image 90
Giorgio Antonioli Avatar answered Sep 28 '22 03:09

Giorgio Antonioli