Reputation: 8408
Since API 27 FragmentPagerAdapter
is deprecated. What's the best alternative to use for this?
In my case, I understand something like super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
would need to be used, but I don't know where within my code this needs to go.
I got these imports in my class:
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
but FragmentPagerAdapter
in class MyViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager){
is crossed out.
class MyViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager){
private val fragmentList : MutableList<androidx.fragment.app.Fragment> = ArrayList()
private val titleList : MutableList<String> = ArrayList()
override fun getItem(position: Int): androidx.fragment.app.Fragment {
return fragmentList[position]
}
override fun getCount(): Int {
return fragmentList.size
}
fun addFragment(fragment: androidx.fragment.app.Fragment, title: String){
fragmentList.add(fragment)
titleList.add(title)
}
override fun getPageTitle(position: Int): CharSequence? {
return titleList[position]
}
}
Upvotes: 104
Views: 93775
Reputation: 4641
If you used this path New > Activities > Tabbed Activity
so you need some changes:
1- XML
before
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/pages"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
after
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/pages"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
2- New Adapter As @Bharat Lalwani wrote below:
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
class ScreenSlidePagerAdapter(activity: FragmentActivity?) : FragmentStateAdapter(activity!!) {
private val mFragmentList: MutableList<Fragment> = ArrayList()
private val mFragmentTitleList: MutableList<String> = ArrayList()
fun getTabTitle(position : Int): String{
return mFragmentTitleList[position]
}
fun addFragment(fragment: Fragment, title: String) {
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
override fun getItemCount(): Int {
return mFragmentList.size
}
override fun createFragment(position: Int): Fragment {
return mFragmentList[position]
}
}
3- Main Activity
before
val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = binding.viewPager
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = binding.tabs
tabs.setupWithViewPager(viewPager)
after
val adapter = ScreenSlidePagerAdapter(this)
adapter.addFragment( PlaceholderFragment.newInstance( 1),"Brand")
adapter.addFragment( PlaceholderFragment.newInstance( 2),"Brand2")
val viewPager: ViewPager2 = binding.viewPager
viewPager.adapter = adapter
viewPager.currentItem = 0
val tabs: TabLayout = binding.tabs
TabLayoutMediator(tabs, viewPager) { tab, position ->
tab.text = adapter.getTabTitle(position)
}.attach()
4- Then you can delete SectionsPagerAdapter class
Upvotes: 6
Reputation: 1520
Switch to ViewPager2 with FragmentStateAdapter.
Here is the XML view:-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
class AdapterTabPager(activity: FragmentActivity?) : FragmentStateAdapter(activity!!) {
private val mFragmentList: MutableList<Fragment> = ArrayList()
private val mFragmentTitleList: MutableList<String> = ArrayList()
public fun getTabTitle(position : Int): String{
return mFragmentTitleList[position]
}
fun addFragment(fragment: Fragment, title: String) {
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
override fun getItemCount(): Int {
return mFragmentList.size
}
override fun createFragment(position: Int): Fragment {
return mFragmentList[position]
}
}
Here is the way to instantiate ViewPager:-
val adapter = AdapterTabPager(activity)
adapter.addFragment(categoryFragment, "Category")
adapter.addFragment(brandFragment, "Brand")
rootView.viewpager.adapter = adapter
rootView.viewpager.currentItem = 0
TabLayoutMediator(rootView.tabs, rootView.viewpager) { tab, position ->
tab.text = adapter.getTabTitle(position)
}.attach()
Upvotes: 16
Reputation: 2846
You can use FragmentStateAdapter(fragment)
class YourViewPagerAdapter(fragment: Fragment, val mFragmentList: Array<String>, val viewPager: ViewPager2) : FragmentStateAdapter(fragment){
override fun getItemCount(): Int {
return mFragmentList.size
}
override fun createFragment(position: Int): Fragment {
when(position){
0 -> return YourFirstTabFragment()
1 -> return YourSecondTabFragment()
2 -> return YourThirdTabFragment()
}
return YourFirstTabFragment()
}
}
Upvotes: 2
Reputation: 1006759
UPDATE 2021-06-14: At this point, ViewPager
itself is all but deprecated. Technically, ViewPager
is not deprecated, but the two concrete PagerAdapter
implementations — FragmentPagerAdapter
and FragmentStatePagerAdapter
— are deprecated. Ideally, switch to something else, such as ViewPager2
or the pager composable in Accompanist.
Replace:
class MyViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager)
with:
class MyViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
(assuming that MyViewPagerAdapter
does not need this value to be configurable)
Upvotes: 153
Reputation: 1633
Need to switch to ViewPager2, they have a migration guide here.
https://developer.android.com/training/animation/vp2-migration#java
Upvotes: 8
Reputation: 21
It seems like not only the constructor without behavior, but the class FragmentPagerAdapter
(which can consume a good amount of memory by keeping Fragments in memory), and FragmentStatePagerAdapter
are both in deprecation stage.
I wonder what can be used to extend abstract class PagerAdapter
to extend codebase lifespan.
Upvotes: 2
Reputation: 25573
The javadocs actually has the following deprecation notice on FragmentPagerAdapter
:
This class is deprecated.
Switch to ViewPager2 and use FragmentStateAdapter instead.
Upvotes: 14