如何使用 NavigationDrawer 和重用相同 TabLayout 的多个片段实现 AppCompatActivity?

How do I implement AppCompatActivity with NavigationDrawer and multiple fragments reusing same TabLayout?

我已经成功地将 TabLayout 与 AppCompatActivity 和 CoordinatorLayout 一起使用,看起来接近这个片段:

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

    <android.support.design.widget.AppBarLayout
        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/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="snap"
            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"
            app:tabGravity="fill"
            app:tabMode="fixed" />

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

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

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

现在我已经实现了 NavigationDrawer,我正在努力在 AppCompatActivity 中显示的其中一个片段中实现选项卡。我希望能够使用 TabLayout 在此 Fragment 内的几个子 Fragment 之间切换。

  1. 如何从我的一个 Fragment 访问 TabLayout?
  2. 如何为每个 Fragment 正确设置 PagerAdapter?
  3. 我在哪里调用 addOnPageChangeListener?
  4. 当我的一个 Fragment 不需要时,如何隐藏 TabLayout 显示选项卡?

1。在一级碎片之间切换

假设布局content.xml代表:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".ui.MyActivity"
    tools:showIn="@layout/my_activity" />

然后,为了能够在Fragments之间切换,实现这个函数:

private void makeTransition(int fragmentId) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        switch (fragmentId) {
            // Fragment with tabs
            case FRAGMENT_TABS:
                fragmentTransaction.replace(R.id.fragment_container, new TabsFragment());
                // This shows TabLayout
                findViewById(R.id.tabs).setVisibility(View.VISIBLE);
                getSupportActionBar().setTitle(R.string.fragment_tabs_title);
                break;
            // Fragment with no tabs
            case FRAGMENT_NO_TABS:
                fragmentTransaction.replace(R.id.fragment_container, new NoTabsFragment());
                // This hides TabLayout
                findViewById(R.id.tabs).setVisibility(View.GONE);
                getSupportActionBar().setTitle(R.string.fragment_no_tabs_title);
                break;
            default:
                throw new RuntimeException("No fragment with ID " + fragmentId + " found");
        }
        fragmentTransaction.commit();
    }

2。从一级 Fragment

访问和设置 TabLayout

TabsFragmentclass中添加一个私有的classTabAdapter:

private class TabAdapter extends FragmentPagerAdapter {

    public TabAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "TAB1";
            case 1:
                return "TAB2";
            // ...
        }
        return null;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return Tab1Fragment.getInstance();
            case 1:
                return Tab2Fragment.getInstance();
            // ...
        }
        return null;
    }

    @Override
    public int getCount() {
        return 2;
    }
}

此外,可选地,实施 ViewPager.OnPageChangeListener:

private class FragmentPageChangeListener implements ViewPager.OnPageChangeListener {

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        Log.d(getClass().getName(), "onPageScrolled");
    }

    @Override
    public void onPageSelected(int position) {
        Log.d(getClass().getName(), "onPageSelected");
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        Log.d(getClass().getName(), "onPageScrollStateChanged");
    }
}

假设您的带有标签的片段的布局是这样的:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true" />

</RelativeLayout>

覆盖 onCreateView 看起来像这样:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.viewpager_fragment, null);

    fragmentPagerAdapter = new TabAdapter(getChildFragmentManager());
    fragmentPageChangeListener = new FragmentPageChangeListener();

    ViewPager pager = (ViewPager) view.findViewById(R.id.viewpager);
    pager.setAdapter(fragmentPagerAdapter);
    pager.addOnPageChangeListener(fragmentPageChangeListener);

    TabLayout tabLayout = (TabLayout) MyAcvtivity.getInstance().findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(pager);

    return view;
}

注意:

在实例化 ViewPager 时在第一级片段中使用 getChildFragmentManager() 而不是 getFragmentManager()