Cha*_*ejo 38

首先,您需要将浮动操作按钮的布局锚定到ViewPager:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/action_bar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            app:tabGravity="center"
            app:tabIndicatorColor="?attr/colorAccent"
            app:tabMode="scrollable"
            app:tabSelectedTextColor="?attr/colorAccent"
            app:tabTextColor="@android:color/black" />

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

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

     <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            app:layout_anchor="@id/viewpager"
            app:layout_anchorGravity="bottom|right|end"
            android:layout_width="56dp"
            android:layout_height="56dp"
            android:src="@drawable/ic_add_white"
            app:borderWidth="@dimen/fab_border_width"
            app:fabSize="normal" />

</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

现在您已经将FAB锚定到ViewPager(注意:我已经在一个片段中尝试了这个,该片段是viewpager中的一个选项卡;它似乎没有正常运行),将OnPageChangeListener添加到ViewPager,如下所示:

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {

            switch (position) {
                case INDEX_OF_TAB_WITH_FAB:
                    fab.show();
                    break;

                default:
                    fab.hide();
                    break;
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
Run Code Online (Sandbox Code Playgroud)

使用新版本的支持库,您可以自动处理切换选项卡上"pop"和"shrink"的动画.


Vin*_*ren 11

这是另一种解决方案.对我来说,与其他问题一样的问题是,将FAB控制权交给包含ViewPager的活动会使得代码难以编码.

我需要通过片段对FAB进行大量控制,以便轻松更改FAB图标并在其上设置特定的侦听器.

粗略地说,步骤是:

  1. 在包含ViewPager的主要活动中声明一个FAB,而不是在片段中声明(这是我想要避免的强制步骤,但是魔术来了之后;否则会让一个好的动画变得困难)
  2. 在ViewPager中显示的每个片段中,我创建了一个可以传递FAB的方法,比如public void shareFab(FloatingActionButton sharedFab); 在此方法中,每个片段将设置FAB图标并添加所需的侦听器
  3. ViewPager.OnPageChangeListener在ViewPager上设置了一个监听器,它将触发动画并调用我的shareFab方法.

因此,每次显示片段时,包含活动将向显示的片段提供FAB的引用.然后片段重置/回收FAB以满足其需要.

这是一个例子:

要显示的片段

public void Fragment1 extends Fragment {

    private FloatingActionButton mSharedFab;

    @Override
    public void onDestroy() {
        super.onDestroy();
        mSharedFab = null; // To avoid keeping/leaking the reference of the FAB
    }

    public void shareFab(FloatingActionButton fab) {
        if (fab == null) { // When the FAB is shared to another Fragment
            if (mSharedFab != null) {
                mSharedFab.setOnClickListener(null);
            }
            mSharedFab = null;
        }
        else {
            mSharedFab = fab;
            mSharedFab.setImageResource(R.drawable.ic_search);
            mSharedFab.setOnClickListener((fabView) -> {
                // Your code
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

容器活动

public class ActivityMain extends AppCompatActivity {

    FloatingActionButton mSharedFab;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mSharedFab = (FloatingActionButton) findViewById(R.id.shared_fab);

        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        Fragment1 fragment1 = new Fragment1();
        Fragment2 fragment2 = new Fragment2();
        adapter.addFragment(fragment1, "Fragment1");
        adapter.addFragment(fragment2, "Fragment2");
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(adapter);

        fragment1.shareFab(mSharedFab); // To init the FAB
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
            @Override
            public void onPageSelected(int position) {  }
            @Override
            public void onPageScrollStateChanged(int state) {
                switch (state) {
                    case ViewPager.SCROLL_STATE_DRAGGING:
                        mSharedFab.hide(); // Hide animation
                        break;
                    case ViewPager.SCROLL_STATE_IDLE:
                        switch (viewPager.getCurrentItem()) {
                            case 0:
                                fragment2.shareFab(null); // Remove FAB from fragment
                                fragment1.shareFab(mSharedFab); // Share FAB to new displayed fragment
                                break;
                            case 1:
                            default:
                                fragment1.shareFab(null); // Remove FAB from fragment
                                fragment2.shareFab(mSharedFab); // Share FAB to new displayed fragment
                                break;
                        }
                        mSharedFab.show(); // Show animation
                        break;
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

......以及主要活动的经典布局

<?xml version="1.0" encoding="utf-8"?>
<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:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="fixed"
            app:tabGravity="fill"/>

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

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"  />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/shared_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin" />

</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

专业人士是:

  • 动画就像材料设计指南中描述的那样!
  • 每个碎片完全控制FAB

缺点是:

  • 由于FAB可以与另一个片段共享,因此每次都应检查FAB的引用,以确保它不为空
  • 在ViewPager级别声明FAB,有点麻烦


Nic*_*hek 7

对于隐藏和显示的好动画使用此:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {
                switch (state){
                    case ViewPager.SCROLL_STATE_IDLE:
                        fab.show();
                        break;
                    case ViewPager.SCROLL_STATE_DRAGGING:
                    case ViewPager.SCROLL_STATE_SETTLING:
                        fab.hide();
                        break;
                }

            }
        });
Run Code Online (Sandbox Code Playgroud)