2

so i have the classic viewpager in a tablayout that looks something like this: enter image description here

My viewPagerAdapter class looks like this:

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

}

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 ?

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: enter image description here

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 ?

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.