wbk727
wbk727

Reputation: 8408

FragmentPagerAdapter deprecated

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

Answers (7)

Mori
Mori

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

Bharat Lalwani
Bharat Lalwani

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

Tippu Fisal Sheriff
Tippu Fisal Sheriff

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

CommonsWare
CommonsWare

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

Need to switch to ViewPager2, they have a migration guide here.

https://developer.android.com/training/animation/vp2-migration#java

Upvotes: 8

Bruno Serralheiro
Bruno Serralheiro

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

Kiskae
Kiskae

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

Related Questions