带有tablayout的android viewpager-如何在标签内添加其他片段? [英] android viewpager with tablayout - how to add other fragments inside of a tab?

查看:71
本文介绍了带有tablayout的android viewpager-如何在标签内添加其他片段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在布局中有一个经典的viewpager,看起来像这样:

so i have the classic viewpager in a tablayout that looks something like this:

我的viewPagerAdapter类如下:

My viewPagerAdapter class looks like this:

公共类HomePagerAdapter扩展FragmentPagerAdapter { int mNumOfTabs;

public class HomePagerAdapter extends 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的片段中,并且希望将其放置在第一个选项卡的顶部.然后,当用户单击后退"按钮时,它将仅回到第一个选项卡中的原始内容.视图分页器可以做到这一点吗?

So now on one of the tabs i need to add a fragment on top of it. so its a search fragment really. i do a search in the tab bar and i want the back end search results to appear in only ONE of the tabs (the first one). but i want the search results displayed in a fragment called searchFragmentResults and i want it to be laid out on top of the first tab. Then when user hits the back button it will just go back to the original content in the first tab. Is this possible with view pager ?

因此,当我在第一个选项卡的tabBar上单击搜索图标时,它应该显示一个searchView,当我搜索用户查询时,它应该显示另一个包含结果的片段,但仅显示在它起始的选项卡中.这是一个例子:

so visually when i hit the search icon on the first tabs tabBar it should bring up a searchView and when i search for the users query it should bring up a another fragment with the results but only in the tab that it started from. Here is an example:

我无法调用fragtransaction.replace(somecontentview, somefragment); (or its add method),因为我没有将它们添加到contentview中.我让viewpager为我做.那么如何实现呢?

i cant call fragtransaction.replace(somecontentview, somefragment); (or its add method) because i did not add them to a contentview. i let the viewpager do it for me. So how is this achieved ?

推荐答案

我想出了如何做到这一点.该选项卡应该是一个片段,其目的是仅包含其他片段.这个想法基于 SO .但是我需要为viewPager做它.让我们逐步进行.首先是viewpager适配器:

i figured out how to do this. The tab should be a fragment who's purpose is to only contain other fragments. the idea is based off of this SO. But i had a need to do it for a viewPager. Lets go through the steps. first the viewpager adapter:

    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];
    }

让我们进入一个容器看看它的外观:

Lets go into a container to see how it would look:

将此内容添加到您所有容器的xml中(以及您在视觉上想要的其他任何内容,但它们都必须具有相同的container_framelayout ID:

add this to your xml for all the containers (along with anything else you want visually but they ALL must have the same id of container_framelayout:

     <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中,我只是发现它可以修复一些错误并可以很好地工作.

you dont have to put it in a coordinatorLayout i just find it fixes some bugs and works well.

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

In your fragments base class i copied almost the same code from the SO i mentioned above but slight modification if you want to add tag or not:

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;
    }

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

Now lets look at the activities layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">


    <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: 其标准:

Now i'll show you how to set up the tablayout in the activity hosting the tablayout: its standard:

    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获取当前片段.

I guess the major part is onBackPress getting the current fragment.

这篇关于带有tablayout的android viewpager-如何在标签内添加其他片段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆