带有tablayout的android viewpager - 如何在选项卡中添加其他片段?

时间:2017-06-25 05:17:58

标签: android android-fragments tabs android-viewpager

所以我在tablayout中有经典的viewpager,看起来像这样: enter image description here

我的viewPagerAdapter类如下所示:

public class HomePagerAdapter扩展FragmentPagerAdapter {     int mNumOfTabs;

public HomePagerAdapter(FragmentManager fm, int NumOfTabs) {
    super(fm);
    this.mNumOfTabs = NumOfTabs;
}

@Override
public Fragment getItem(int position) {

    switch (position) {
        case 0:
            TabHomeFragment tab1 = new TabHomeFragment();
            return tab1;
        case 1:
            TabShopFragment tab2 = new TabShopFragment();
            return tab2;
        case 2:
            TabMeFragment tab3 = new TabMeFragment();
            return tab3;
        default:
            return null;
    }
}

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

}

所以现在在其中一个标签上我需要在它上面添加一个片段。所以它真的是一个搜索片段。我在标签栏中进行搜索,我希望后端搜索结果只出现在其中一个标签中(第一个)。但我希望搜索结果显示在一个名为searchFragmentResults的片段中,我希望它显示在第一个选项卡的顶部。然后,当用户点击后退按钮时,它将返回到第一个选项卡中的原始内容。这可以通过view pager进行吗?

如此直观地当我点击第一个标签tabBar上的搜索图标时,它应该显示一个searchView,当我搜索用户查询时,它应该显示另一个包含结果的片段,但仅在它开始的标签中。这是一个例子: enter image description here

我无法致电fragtransaction.replace(somecontentview, somefragment); (or its add method)因为我没有将它们添加到内容视图中。我让viewpager为我做了。那么这是如何实现的?

1 个答案:

答案 0 :(得分:1)

我想出了如何做到这一点。选项卡应该是一个片段,其目的是仅包含其他片段。这个想法是基于这个SO。但是我需要为viewPager做这件事。让我们完成这些步骤。首先是viewpager适配器:

    public class HomePagerAdapter extends FragmentStatePagerAdapter {

    //integer to count number of tabs
    int tabCount;
    private Fragment mCurrentFragment;

    private String[] tabTitles = new String[]{"tab0", "tab1", "tab2, "tab3"};

    //Constructor to the class
    public HomePagerAdapter(FragmentManager fm, int tabCount) {
        super(fm);
        this.tabCount = tabCount;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                TabHomeContainerFragment tab1 = new Tab0ContainerFragment();
                return tab1;
            case 1:
                TabShopFragment tab2 = new Tab1ContainerFragment(); 
                return tab2;
            case 2:
                TabMeFragment tab3 = new Tab2ContainerFragment();
                return tab3;
            case 3:
                TabBagFragment tab4 = new Tab3ContainerFragment();
                return tab4;
            default:
                return null;
        }
    }

    //Overriden method getCount to get the number of tabs
    @Override
    public int getCount() {
        return tabCount;
    }

    public Fragment getCurrentFragment() {
        return mCurrentFragment;
    }
//* this is key to get the current tab to pop the fragments afterwards**/
    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        if (getCurrentFragment() != object) {
            mCurrentFragment = ((Fragment) object);
        }
        super.setPrimaryItem(container, position, object);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }

让我们进入一个容器,看看它的样子:

将这个添加到您的xml中以获取所有容器(以及您想要的任何其他内容,但它们必须具有相同的container_framelayout的id:

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

<FrameLayout android:id="@+id/container_framelayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android" />

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

你不必把它放在一个coordinatorLayout我发现它修复了一些错误并且运行良好。

在你的片段基类中,我复制了几乎与上面提到的SO相同的代码,但是如果你想添加标签则稍作修改:

public void replaceFragment(Fragment fragment, boolean addToBackStack,String tag) {
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        if (addToBackStack) {
            transaction.addToBackStack(null);
        }
        transaction.replace(R.id.container_framelayout, fragment,tag);
        transaction.commit();
        getChildFragmentManager().executePendingTransactions();
    }

    public boolean popFragment() {
        Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
        boolean isPop = false;
        if (getChildFragmentManager().getBackStackEntryCount() > 0) {
            isPop = true;
            getChildFragmentManager().popBackStack();
        }
        return isPop;
    }

现在让我们看一下活动布局:

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:background="@color/white"/>

<android.support.design.widget.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabMode="fixed"
    app:tabGravity="fill"
    app:tabTextColor="@color/black"
    app:tabSelectedTextColor="@android:color/darker_gray"
    />

现在,我将向您展示如何在托管tablayout的活动中设置tablayout: 它的标准:

    public class HomePageActivity  implements TabLayout.OnTabSelectedListener {

               private final int NUM_OF_TABS = 4;

               @BindView(R.id.pager)
               public ViewPager viewPager;

               public HomePagerAdapter adapter;

               @BindView(R.id.tabLayout)
               TabLayout tabLayout;

               @NonNull
               @Override
               public HomePagePresenter createPresenter() {
                   return new HomePagePresenter();
               }

               @Override
               protected void onCreate(Bundle savedInstanceState) {
                   super.onCreate(savedInstanceState);
                   setContentView(R.layout.activity_homepage);
                   ButterKnife.bind(this);
                   initView();
               }

               private void initView() {

                   for (int i = 0; i < NUM_OF_TABS; i++)
                       tabLayout.addTab(tabLayout.newTab());

                   adapter = new HomePagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());

                   //Adding adapter to pager
                   viewPager.setAdapter(adapter);

                   tabLayout.addOnTabSelectedListener(this);

                   tabLayout.setupWithViewPager(viewPager);

                   // configure tab icons
                   int[] imageTabResId = {
                           R.drawable.welcome1,
                           R.drawable.welcome2,
                           R.drawable.welcome3,
                           R.drawable.welcome1};

                   for (int i = 0; i < imageTabResId.length; i++) {
                       tabLayout.getTabAt(i).setIcon(imageTabResId[i]);
                   }
               }

/** this is key. we get the current fragment showing and pop it **/
               @Override
               public void onBackPressed() {
                   boolean isPopFragment = false;
                   isPopFragment = ((BaseFragment) adapter.getCurrentFragment()).popFragment();
                   if (!isPopFragment) {
                       finish();
                   }
               }

               @Override
               public void onTabSelected(TabLayout.Tab tab) {
                   viewPager.setCurrentItem(tab.getPosition());
               }

               @Override
               public void onTabUnselected(TabLayout.Tab tab) {

               }

               @Override
               public void onTabReselected(TabLayout.Tab tab) {

               }
           }

我猜主要部分是onBackPress获取当前片段。