我应该在片段中使用嵌套片段吗?

时间:2018-01-31 22:48:37

标签: android android-fragments android-activity android-tablayout

我有一个主活动,它使用AHBottomNavigationView作为屏幕底部的菜单。当单击一个不同的菜单项时,它会创建一个与该菜单项对应的新片段,其逻辑如此(为了简化这个问题,精简的switch语句):

fragmentManager.beginTransaction().replace(R.id.content_id, New TheFragmentForTheTabClicked).commit();

其中content_id是主要活动的ConstraintLayout的ID。

在我的第一个导航菜单项的片段中,还有两个选项卡(使用TabLayout),用另一个片段替换屏幕空间。这是通过将FragmentPagerAdapter设置到ViewPager上来完成的,因此点击每个选项卡会更改子片段。所以此时,嵌套在类中的片段中嵌套了一个片段。通常是这样的:

 Main Activity  
 |
 +-- Fragment 1 (selected from AHBottomNavigationView)
 |   |
 |   +-- Sub-Fragment 1 (selected by clicking the first tab in Fragment 1)
 |   |
 |   +-- Sub-Fragment 2 (selected by clicking the second tab in Fragment 1)
 |
 +-- Fragment 2 (selected from AHBottomNavigationView)
 |
 +-- Fragment 3 (selected from AHBottomNavigationView)
 |
 +-- Fragment 4 (selected from AHBottomNavigationView)

所以我的问题是: 我这样做的方式是否正确,如果没有,那么更好的方法是什么? 此外,我发现当我第一次选择片段1时,两个标签之间的滑动和点击工作正常,但是如果我点击不同的底部导航菜单项(即片段3)然后返回,我得到以下两个问题:

  1. 未显示任何子片段中的内容
  2. 在两个标签之间滑动不再有效。我不得不完全拉过屏幕,因为指示器会在两个标签之间“卡住”。
  3. 如果我能提供更多信息,请告诉我,我会。

    Fragment1.java:

    package com.mypackage.mypackage;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.design.widget.TabLayout;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.view.ViewPager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    /**
     * A simple {@link Fragment} subclass.
     */
    public class Fragment1 extends Fragment {
    
        private FragmentActivity mContext;
    
        public Fragment1() {
        }
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_1, container, false);
    
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState){
            super.onActivityCreated(savedInstanceState);
    
            // Find the view pager that will allow the user to swipe between fragments
            ViewPager viewPager = (ViewPager) getView().findViewById(R.id.viewpager);
    
            // Create an adapter that knows which fragment should be shown on each page
            // using getFragmentManager() will work too
            Fragment1PagerAdapter adapter = new Fragment1PagerAdapter(mContext.getSupportFragmentManager(), mContext);
    
            // Set the adapter onto the view pager
            viewPager.setAdapter(adapter);
    
            TabLayout tabLayout = (TabLayout) getView().findViewById(R.id.sliding_tabs);
            tabLayout.setupWithViewPager(viewPager);
        }
    
        /**
         * Override to set context.  This context is used for getSupportFragmentManager in onCreateView
         * @param activity
         */
        @Override
        public void onAttach(Activity activity) {
            mContext=(FragmentActivity) activity;
            super.onAttach(activity);
        }
    
    }
    

    fragment_1.xml          

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <android.support.design.widget.TabLayout
                android:id="@+id/sliding_tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabMode="fixed"
                app:tabBackground="@color/fragment1TabBackground"
                app:tabIndicatorColor="@color/fragment1TabIndicatorColor"/>
    
            <android.support.v4.view.ViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="0px"
                android:layout_weight="1"/>
    
        </LinearLayout>
    
    
    </android.support.constraint.ConstraintLayout>
    

    Fragment1PagerAdapter.java

    package com.mypackage.mypackage;
    
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    import android.content.Context;
    
    
    public class Fragment1PagerAdapter extends FragmentPagerAdapter {
    
        private Context context;
    
        public Fragment1PagerAdapter(FragmentManager fm, Context mContext){
            super(fm);
            context = mContext;
    
        }
    
        @Override
        public Fragment getItem(int position){
            if (position == 0){
                return new SubFragment1();
            }
            else{
                return new SubFragment2();
            }
        }
    
        @Override
        public int getCount() {return 2;}
    
        @Override
        public CharSequence getPageTitle(int position) {
    
            switch(position){
                case 0:
                    return context.getResources().getString(R.string.sub_fragment_1_page_title);
                case 1:
                    return context.getResources().getString(R.string.sub_fragment_2_page_title);
                default:
                    return null;
            }
        }
    }
    

1 个答案:

答案 0 :(得分:2)

Fragments嵌套在FragmentViewPager并将滑动功能FragmentManager嵌套到需要提供给Adapter的{​​{1}}时,请使用:{{1而不是getChildFragmentManager()getSupportFragmentManager()。因为两者实际上都与getFragmentManager()而不是Activities相关,正如文档所述,与getChildFragmentManager()有关:

  

返回私有FragmentManager以放置和管理碎片   在这片段中。