23720

android viewpager with tablayout - how to add other fragments inside of a tab?

so i have the classic viewpager in a tablayout that looks something like this: <img src=https://www.e-learn.cn/content/wangluowenzhang/"https://i.stack.imgur.com/LqF0J.png" alt="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: <img src=https://www.e-learn.cn/content/wangluowenzhang/"https://i.stack.imgur.com/YBYFb.png" alt="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 ?

Answer1:

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:

<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.

Recommend

  • Spring MVC @RequestParam a list of objects
  • Facebook PHP SDK 3 won't work on 32-bit system, facebook ids treated as int and can be > 214
  • Changing the user agent in Chromium Embedded 3 (DCEF3) (CefVCL)
  • Replace any string in columns with 1
  • Conversion from C++ to Delphi (simple)
  • Java, will (low + high) >>> 1 overflow?
  • PyYaml parses '9:00' as int
  • How to escape colon (:) character while executing native SQL queries against an Informix database us
  • how to pass value from asp.net server control using jQuery?
  • Deliberately simplifying fractional exponents
  • BizTalk Party not being resolved for incoming HL7v2 message
  • How are 32 bit JavaScript numbers resulting from a bit-wise operation converted back to 64 bit numbe
  • JsonMappingException: Can not deserialize instance of java.lang.Integer out of START_OBJECT token
  • VB.Net Double comparison after some additions
  • Unicorn and Rails eat up 2x MySQL connections
  • Upper limits for fibonnacci
  • Smack 4.1.0 android Roster not displaying
  • Need code translation from VB to C#
  • Using Sax parsing to edit and write XML in VB6
  • Z3: Convert between FP and BitVector?
  • Should I or shouldn't I use the CachingConnectionFactory with hornetq 2.4.1
  • Date Conversion from yyyy-mm-dd to dd-mm-yyyy
  • C++ Partial template specialization - design simplification
  • Django: Count of Group Elements
  • Is there a javascript serializer for JSON.Net?
  • Counter field in MS Access, how to generate?
  • Sending data from AppleScript to FileMaker records
  • MySQL WHERE-condition in procedure ignored
  • Where to put my custom functions in Wordpress?
  • Javascript + PHP Encryption with pidCrypt
  • Convert array of 8 bytes to signed long in C++
  • Buffer size for converting unsigned long to string
  • Getting Messege Twice Using IMvxMessenger
  • How to stop GridView from loading again when I press back button?
  • Binding checkboxes to object values in AngularJs
  • How can i traverse a binary tree from right to left in java?
  • How can I use threading to 'tick' a timer to be accessed by other threads?