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.