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:
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>
you dont have to put it in a coordinatorLayout i just find it fixes some bugs and works well.
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" />
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) { } }
I guess the major part is onBackPress getting the current fragment.