且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

带有tablayout的android viewpager-如何在标签内添加其他片段?

更新时间:2023-10-28 12:48:46

我想出了如何做到这一点.该选项卡应该是一个片段,其目的是仅包含其他片段.这个想法基于 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.