Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android TabLayout inside Fragment

Tags:

I am using Navigation Drawer to navigate between fragments they all use the MainActivity toolbar but each fragment has it's own TabLayout with 3 tabs and in each tab I am using RecyclerView to show different text and images.

I did this last time using actvities instead of fragments but now using the drawer it's beter to use fragments.

I have got to a point where the tabs work but as soon as I put the ViewPager in and connect the adapters to the tabs and I open the new fragment from the drawer I get a Null Pointer what could be the 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) 
like image 475
Jacques Krause Avatar asked Jan 28 '16 10:01

Jacques Krause


People also ask

Can we use TabLayout in fragment in Android?

You will have to deal with nested fragments inside pager. All page content must be there and TabLayout must be in the same layout where you ViewPager is. My project is a bit old, and I used android. support.

Can we use TabLayout without ViewPager in Android?

It is possible to use a TabLayout without a ViewPager by using a TabLayout. OnTabSelectedListener . For navigation within an Activity , manually populate the UI based on the tab selected.


2 Answers

After looking into yours code, I found that you forget to return a fragment in getItem method of PagerAdapter that you overrided from the FragmentStatePagerAdapter and there is no break statement in each case due to which every time a null value was returned.

To doing so you need to create a another new fragment for each page in ViewPager or you can create one new fragment that could use in all page of ViewPager.

You can't use the same recyclerview into the tabs of view pager that you have defined in 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 have fixed your fragment and created a new Fragment that you can use in 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 View Pager (or you can create different fragment for each page according to yours need).

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> 
like image 149
Aman Jain Avatar answered Oct 21 '22 06:10

Aman Jain


Use getChildFragmentManager() instead of getSupportFragmentManager()

like image 33
madhu527 Avatar answered Oct 21 '22 05:10

madhu527