Android TabLayout inside fragment

I use Navigation Drawer to move between fragments, they all use the MainActivity toolbar, but each fragment has its own TabLayout with 3 tabs, and on each tab I use RecyclerView to display different text and images.

I did this one last time using actvities instead of fragments, but now using a box, he used beter to use fragments.

I have a point where the tabs work, but as soon as I insert the ViewPager and connect the adapters to the tabs and I open a new fragment from the box, I get a Null Pointer, which may be a problem Here?

MainActivity.java

 public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); } @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); return id == R.id.action_settings || super.onOptionsItemSelected(item); } @Override public boolean onNavigationItemSelected(MenuItem item) { int id = item.getItemId(); Fragment fragment; if (id == R.id.fragment_one) { fragment = new NewFragment(); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.container, fragment); ft.commit(); } else if (id == R.id.fragment_two) { fragment = new NewFragment(); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.container, fragment); ft.commit(); } else if (id == R.id.fragment_three) { fragment = new NewFragment(); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.container, fragment); ft.commit(); } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } } 

activity_main.xml

 <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.xcandy.guideforfifa17.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" /> </android.support.design.widget.CoordinatorLayout> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout> 

NewFragment.java

 public class NewFragment extends Fragment { private RecyclerView mRecyclerView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.activity_fragment_one, container, false); TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs); tabLayout.addTab(tabLayout.newTab().setText("A")); tabLayout.addTab(tabLayout.newTab().setText("B")); tabLayout.addTab(tabLayout.newTab().setText("C")); final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager); mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity()); mRecyclerView.setLayoutManager(mLayoutManager); viewPager.setAdapter(new PagerAdapter (getFragmentManager(), tabLayout.getTabCount())); viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @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) { } }); return view; } public class PagerAdapter extends FragmentStatePagerAdapter { int mNumOfTabs; public PagerAdapter(FragmentManager fm, int NumOfTabs) { super(fm); this.mNumOfTabs = NumOfTabs; } @Override public Fragment getItem(int position) { switch (position) { case 0: RecyclerView.Adapter mAdapter = new AdapterOne(); mRecyclerView.setAdapter(mAdapter); case 1: mAdapter = new AdapterTwo(); mRecyclerView.setAdapter(mAdapter); case 2: mAdapter = new AdapterThree(); mRecyclerView.setAdapter(mAdapter); default: return null; } } @Override public int getCount() { return mNumOfTabs; } } } 

activity_fragment.xml

 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".NewFragment"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" app:tabGravity="fill"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white"/> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.design.widget.CoordinatorLayout> 

Error log

  --------- beginning of crash 06-23 11:19:56.985 2466-2466/com.candyx.sims E/AndroidRuntime: FATAL EXCEPTION: main Process: com.candyx.sims, PID: 2466 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference at com.candyx.sims.BlankFragment.onCreateView(BlankFragment.java:38) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 06-23 11:23:14.912 5839-5873/com.candyx.sims D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true [ 06-23 11:23:14.920 5839: 5839 D/ ] HostConnection::get() New Host Connection established 0xb4125190, tid 5839 06-23 11:23:14.927 5839-5839/com.candyx.sims D/Atlas: Validating map... 06-23 11:23:15.011 5839-5873/com.candyx.sims I/OpenGLRenderer: Initialized EGL, version 1.4 06-23 11:23:15.027 5839-5873/com.candyx.sims D/OpenGLRenderer: Enabling debug mode 0 06-23 11:23:15.039 5839-5873/com.candyx.sims W/EGL_emulation: eglSurfaceAttrib not implemented 06-23 11:23:15.039 5839-5873/com.candyx.sims W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xae838600, error=EGL_SUCCESS 06-23 11:23:16.444 5839-5839/com.candyx.sims W/PathParser: Points are too far apart 4.000000596046461 06-23 11:23:17.342 5839-5839/com.candyx.sims W/PathParser: Points are too far apart 4.000000596046461 06-23 11:23:17.350 5839-5839/com.candyx.sims I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead. 06-23 11:23:17.369 5839-5839/com.candyx.sims D/AndroidRuntime: Shutting down VM 06-23 11:23:17.369 5839-5839/com.candyx.sims E/AndroidRuntime: FATAL EXCEPTION: main Process: com.candyx.sims, PID: 5839 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference at com.candyx.sims.NewFragment.onCreateView(NewFragment.java:38) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 06-23 11:25:16.961 7518-7518/com.candyx.sims W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable 06-23 11:25:17.078 7518-7548/com.candyx.sims D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true [ 06-23 11:25:17.081 7518: 7518 D/ ] HostConnection::get() New Host Connection established 0xb412a1f0, tid 7518 06-23 11:25:17.082 7518-7518/com.candyx.sims D/Atlas: Validating map... 06-23 11:25:17.109 7518-7548/com.candyx.sims I/OpenGLRenderer: Initialized EGL, version 1.4 06-23 11:25:17.126 7518-7548/com.candyx.sims D/OpenGLRenderer: Enabling debug mode 0 06-23 11:25:17.134 7518-7548/com.candyx.sims W/EGL_emulation: eglSurfaceAttrib not implemented 06-23 11:25:17.134 7518-7548/com.candyx.sims W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xb41234c0, error=EGL_SUCCESS 06-23 11:25:31.030 7518-7518/com.candyx.sims W/PathParser: Points are too far apart 4.000000596046461 06-23 11:25:32.174 7518-7518/com.candyx.sims W/PathParser: Points are too far apart 4.000000596046461 06-23 11:25:32.187 7518-7518/com.candyx.sims I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead. 06-23 11:25:32.207 7518-7518/com.candyx.sims D/AndroidRuntime: Shutting down VM 06-23 11:25:32.207 7518-7518/com.candyx.sims E/AndroidRuntime: FATAL EXCEPTION: main Process: com.candyx.sims, PID: 7518 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference at com.candyx.sims.NewFragment.onCreateView(NewFragment.java:38) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
+7
android android-fragments android-recyclerview android-tablayout
source share
6 answers

After examining your code, I found that you forget to return the fragment to the getItem PagerAdapter method, which you redefined from the FragmentStatePagerAdapter, and in each case there is no break statement, due to which a null value is returned each time.

To do this, you need to create a new new fragment for each page in the ViewPager, or you can create one new fragment that can be used on all ViewPager pages.

You cannot use the same recyclerview in the view pager tabs that you defined in the parent fragment.

activity_fragment_one.xml

  <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".NewFragment"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" app:tabTextAppearance="?android:attr/textAppearanceMedium" app:tabTextColor="#ffffff" android:layout_height="?android:actionBarSize" app:tabMode="fixed" app:tabGravity="fill"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:background="@android:color/white"/> </android.support.design.widget.CoordinatorLayout> 

I fixed your fragment and created a new fragment that can be used on ViewPager pages.

 public class NewFragment extends Fragment { private RecyclerView mRecyclerView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.activity_fragment_one, container, false); TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs); tabLayout.addTab(tabLayout.newTab().setText("A")); tabLayout.addTab(tabLayout.newTab().setText("B")); tabLayout.addTab(tabLayout.newTab().setText("C")); final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager); // mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity()); mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); //mRecyclerView.setLayoutManager(mLayoutManager); viewPager.setAdapter(new PagerAdapter(getFragmentManager(), tabLayout.getTabCount())); viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.setupWithViewPager(viewPager); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @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) { } }); return view; } public class PagerAdapter extends FragmentStatePagerAdapter { int mNumOfTabs; public PagerAdapter(FragmentManager fm, int NumOfTabs) { super(fm); this.mNumOfTabs = NumOfTabs; } @Override public Fragment getItem(int position) { switch (position) { case 0: return new FragmentTab(); case 1: return new FragmentTab(); case 2: return new FragmentTab(); default: return null; } } @Override public int getCount() { return mNumOfTabs; } } } 

FragmentTab for each page in the Pager view (or you can create a separate fragment for each page according to your needs).

 public class FragmentTab extends Fragment { RecyclerView mRecyclerView; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_tab, container, false); mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity()); mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); RecyclerView.Adapter mAdapter = new AdapterOne(); mRecyclerView.setAdapter(mAdapter); return view; } } 

fragment_tab.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> 
+9
source share

Without error logs, it's hard to tell where and why you get a NullPointerException .

The first thing that caught my attention was that you did not TabLayout your TabLayout and ViewPager . Use the following code after installing the adapter for ViewPager :

 // setUpWithViewPager doesn't work without using a Runnable interface. // Support library bug, maybe? tabLayout.post(new Runnable() { @Override public void run() { tabLayout.setupWithViewPager(viewPager); } }); 

I'm not sure if this is a problem, but try :)

+2
source share

Use getChildFragmentManager() instead of getSupportFragmentManager()

+1
source share

This getItem method in the PagerAdapter incorrect, it returns a Fragment init. You must return a Fragment . And in the fragment you setView recyclerView to it

0
source share

I suggest using getChildFragmentManager instead of getFragmentManager in

viewPager.setAdapter(new PagerAdapter (getFragmentManager(), tabLayout.getTabCount()));

0
source share

Well, some time ago I implemented the exact same application design. I had a snippet designed to store tabs and ViewPager. It was a difficult task, and I remember that I faced the same problems as you. Here's how I solved it:

Layout Sequence:

Activity -> Fragment -> Tab Layout + ViewPager -> FragmentStatePagerAdapter -> Fragment -> RecyclerView

You have nothing to do with the main activity. These are all fragments. So get rid of TabLayout in activity_main.xml .

You will have to deal with nested fragments inside the pager. The entire content of the page should be there, and the TabLayout should be in the same layout as the ViewPager.

My project is a bit old, and I used android.support.v4.app.Fragment if that makes sense. I have stripped data sources that you don’t need, so you can see that this refers to some of the lost methods.

The task was to display a price list with categories and display each product category on its own page, so that horizontal scrolling switched categories and vertical strokes - listed products.

Each snippet with ViewPager and TabLayout has the following subfragment_price_list_pager.xml layout:

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/icons" app:cardCornerRadius="4dp" app:cardElevation="4dp" app:cardPreventCornerOverlap="true"> <android.support.v7.widget.Toolbar android:id="@+id/priceListToolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:elevation="4dp" android:theme="@style/AppTheme.Toolbar.TabLayout" app:navigationIcon="@drawable/ic_tag_multiple_grey600_24dp" tools:ignore="UnusedAttribute"> <android.support.design.widget.TabLayout android:id="@+id/tabBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> </android.support.v7.widget.Toolbar> <android.support.v4.view.ViewPager android:id="@+id/priceList" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="58dp" android:padding="5dp" android:scrollbars="horizontal" /> </android.support.v7.widget.CardView> 

Here is PriceListPagerFragment.class :

 public class PriceListPagerFragment extends Fragment { private static final String TAG = "PriceListPagerFragment"; private PriceList mPriceList; private ViewPager mCategoriesViewPager; private TabLayout tabLayout; private Loader<PriceList> priceListLoader; private EditText scanerBarcodeText; private OnCartActionListener mListener; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.subfragment_price_list_pager, container, false); // Pager that would be inflated with page fragments. mCategoriesViewPager = (ViewPager) rootView.findViewById(R.id.priceList); tabLayout = (TabLayout) rootView.findViewById(R.id.tabBar); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); // Do all the stuff with pager here: updatePriceListPages(); return rootView; } private void updatePriceListPages() { if (mCategoriesViewPager != null && mPriceList != null) { Log.d(TAG, this + "updatePriceListPages"); if (mCategoriesViewPager.getAdapter() == null) { PriceListCategoriesAdapter adapter = new PriceListCategoriesAdapter( getFragmentManager(), tabLayout ); mCategoriesViewPager.setAdapter( adapter ); // Each page is a content of a single category of one-level catalog // We did not supply catalog to adapter before it is bound to ViewPager for some serious reason which I can't recall now adapter.setPriceList(mPriceList); tabLayout.setupWithViewPager(mCategoriesViewPager); } else { ((PriceListCategoriesAdapter) mCategoriesViewPager.getAdapter()).setPriceList(mPriceList); } } } } 

Custom FragmentStatePagerAdapter implementation, PriceListCategoriesAdapter.class :

 public class PriceListCategoriesAdapter extends FragmentStatePagerAdapter { private static final String TAG = "PriceListCategoriesAd"; private final TabLayout mTabLayout; private FragmentManager mFm; private Vector<PriceListFragment> recyclerViewList; private Vector<String> titles; public PriceListCategoriesAdapter(FragmentManager fm, TabLayout tabLayout) { super(fm); mFm = fm; mTabLayout = tabLayout; recyclerViewList = new Vector<>(); titles = new Vector<>(); } // All the magic with nested page fragments is done here public void setPriceList(PriceList priceList) { boolean updateTabs = false; Vector<String> newTitles = new Vector<>(); int position = 0; for (CatalogItem catalogItem : priceList.getCatalogs()) { if (catalogItem.getProducts() == null) continue; boolean newFragment; PriceListFragment fragment; try { fragment = recyclerViewList.get(position); newFragment = false; } catch (ArrayIndexOutOfBoundsException e) { fragment = new PriceListFragment(); newFragment = true; } fragment.setCatalogItem(catalogItem); newTitles.add(catalogItem.getName()); if (newFragment) { recyclerViewList.add(fragment); } position++; } if (titles.size() != newTitles.size()) { updateTabs = true; } else { for (int position = 0; position < titles.size(); position++) { if (!titles.get(position).equals(newTitles.get(position))) { updateTabs = true; break; } } } titles = newTitles; notifyDataSetChanged(); if (updateTabs) mTabLayout.setTabsFromPagerAdapter(this); } @Override public Fragment getItem(int position) { return recyclerViewList.get(position); } @Override public int getItemPosition(Object object) { PriceListFragment fragment = (PriceListFragment) object; String title = (String) fragment.getTitle(); int position = titles.indexOf(title); if (position >= 0) { return position; } else { return POSITION_NONE; } } @Override public int getCount() { return titles.size(); } @Override public CharSequence getPageTitle(int position) { return recyclerViewList.get(position).getTitle(); } // We don't keep states @Override public Parcelable saveState() { return null; } // We don't keep states @Override public void restoreState(Parcelable state, ClassLoader loader) { } } 

And finally, PriceListFragment layout:

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.RecyclerView android:id="@+id/categoryList" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" /> 
Himself

PriceListFragment.class has nothing special. Just create an instance of RecyclerView with the correct data.

0
source share