I use the code below to setup my TabLayout inside a Fragment. The problem is that the tabs are not swiping even though I used registerOnPageChangeCallback()
. When I add fragment containing tablayout to a bottom navigation view then when swiping the tablayout goes to a white screen with no fragments. What am I doing wrong?
If i use tablayout in activity it can be swiped as usual.
public class BookcaseFragment extends Fragment {
private TabLayout tabLayout;
private ViewPager2 mViewPager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_bookcase, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tabLayout = view.findViewById(R.id.tab_layout_bookcase);
mViewPager = view.findViewById(R.id.bookcase_viewpager);
BookcaseViewPagerAdapter adapter = new BookcaseViewPagerAdapter(this);
mViewPager.setAdapter(adapter);
new TabLayoutMediator(tabLayout, mViewPager, (tab, position) -> {
switch (position){
case 0:
tab.setText("following");
break;
case 1:
tab.setText("downloaded");
break;
case 2:
tab.setText("watched");
break;
}
}).attach();
mViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
tabLayout.getTabAt(position).select();
System.out.println(position);
}
});
}
}
public class BookcaseViewPagerAdapter extends FragmentStateAdapter {
public BookcaseViewPagerAdapter(@NonNull Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new FollowingFragment();
case 1:
return new DownloadedFragment();
case 2:
return new JustWatchedFragment();
default:
return new FollowingFragment();
}
}
@Override
public int getItemCount() {
return 3;
}
}
CodePudding user response:
This could be caused by the viewpager being null. Did you make the viewpager in the fragment itself?
I was able to get it to swipe as long as I put the viewpager inside the fragments xml.
written in kotlin, sorry, but should still be the same idea.
class BookcaseFragment : Fragment() {
private var tabLayout: TabLayout? = null
private var mViewPager: ViewPager2? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_bookcase, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tabLayout = view.findViewById(R.id.tab_layout_bookcase)
mViewPager = view.findViewById(R.id.bookcase_pager)
val adapter = BookcaseViewPagerAdapter(this)
adapter.addFragment(BlankFragment())
adapter.addFragment(BlankFragment())
adapter.addFragment(BlankFragment())
mViewPager?.adapter = adapter
tabLayout?.let { tabs->
mViewPager?.let { pager->
TabLayoutMediator(tabs, pager,
TabConfigurationStrategy { tab: TabLayout.Tab, position: Int ->
when (position) {
0 -> tab.text = "following"
1 -> tab.text = "downloaded"
2 -> tab.text = "watched"
}
}).attach()
pager.registerOnPageChangeCallback(object : OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
tabs.getTabAt(position)!!.select()
println(position)
}
})
}
}
}
}
class BookcaseViewPagerAdapter(fragment: Fragment) :
FragmentStateAdapter(fragment) {
private val arrayList: ArrayList<Fragment> = ArrayList()
fun getItem(position: Int): Fragment {
return arrayList[position]
}
fun addFragment(fragment: Fragment) {
arrayList.add(fragment)
}
override fun getItemCount(): Int {
return arrayList.size
}
override fun createFragment(position: Int): Fragment {
return arrayList[position]
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BookcaseFragment">
<androidx.viewpager2.widget.ViewPager2
android:id="@ id/bookcase_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager2.widget.ViewPager2>
<com.google.android.material.tabs.TabLayout
android:id="@ id/tab_layout_bookcase"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</com.google.android.material.tabs.TabLayout>
</FrameLayout>
you can find more information in this answer. Proper implementation of ViewPager2 in Android