【问题标题】:FragmentStateAdapter and ViewPager2 is loading fragment slower than FragmentStatePagerAdapter and ViewPagerFragmentStateAdapter 和 ViewPager2 加载片段的速度比 FragmentStatePagerAdapter 和 ViewPager 慢
【发布时间】:2021-08-24 14:20:15
【问题描述】:

在我的应用程序中,我显示了可以滚动到上个月和下个月的月历列表。在滑动到上一个和下一个时,如果我使用 FragmentStatePagerAdapter 和 ViewPager,我的片段可以顺利加载,没有任何延迟,但它现在已被弃用。所以,我更新了

ViewPager 到 ViewPager2 

FragmentStatePagerAdapter 到 FragmentStateAdapter 

更新后,我可以看到在上下滑动时加载片段有延迟。但是相同的代码可以顺利地使用 FragmentStatePagerAdapter 和 ViewPager。 我也试过mViewPager2.setOffscreenPageLimit(//Interger Value//),但没有帮助。

请帮助我。

fragment_employee_months_holder

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/fragment_months_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:focusable="true" />

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:backgroundTint="@color/colorPrimary" />

</RelativeLayout>

EmployeeSummaryAdapter

class EmployeeSummaryAdapter(
    fragment: Fragment,
    private val mCodes: List<String>,
    private val mListener: NavigationListener,
    private val progressBarInterface: ProgressBarInterface
) : FragmentStateAdapter(fragment) {

    private val mFragments = SparseArray<EmployeeSummaryFragment>()

    override fun createFragment(position: Int): EmployeeSummaryFragment {
        val bundle = Bundle()
        val code = mCodes[position]
        bundle.putString(DAY_CODE, code)

        val fragment = EmployeeSummaryFragment(progressBarInterface)
        fragment.arguments = bundle
        fragment.listener = mListener
        mFragments.put(position, fragment)
        
        return fragment
    }

    override fun getItemCount(): Int = mCodes.size

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }
}

EmployeeSummaryFragmentHolder

class EmployeeSummaryFragmentHolder : MyFragmentHolder(), NavigationListener, ProgressBarInterface {

    private var viewPager2: ViewPager2? = null
    private lateinit var mEmployeeSummaryAdapter: EmployeeSummaryAdapter
    private lateinit var mView: View

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        currentDayCode = Formatter.getTodayCode()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mView = inflater.inflate(R.layout.fragment_employee_months_holder, container, false)
        viewPager2 = mView.fragment_months_viewpager
        viewPager2!!.id = (System.currentTimeMillis() % 100000).toInt()

        Handler(Looper.getMainLooper()).postDelayed({
            setupFragment()
        }, 0)

        return mView
    }

    private fun setupFragment() {
        val codes = getMonths(currentDayCode)
        mEmployeeSummaryAdapter = EmployeeSummaryAdapter(this, codes, this, this)
        viewPager2.apply {
            viewPager2!!.adapter = mEmployeeSummaryAdapter

            val myPageChangeCallback = object : ViewPager2.OnPageChangeCallback() {
                override fun onPageScrollStateChanged(state: Int) { }
                override fun onPageScrolled(position: Int, positionOffset: Float, 
                                              positionOffsetPixels: Int) { }
                override fun onPageSelected(position: Int) {   }
            }
            viewPager2!!.registerOnPageChangeCallback(myPageChangeCallback)
        }
    }
}

EmployeeSummaryFragment

class EmployeeSummaryFragment(val progressBarInterface: ProgressBarInterface) :
    Fragment(), MonthlyCalendar {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_employee_month, container, false)
        ...
        ...        
        return view
    }

    override fun onResume() {
        super.onResume()
        ...
        ...
    }
}

【问题讨论】:

    标签: android android-viewpager fragmentstatepageradapter fragmentstateadapter


    【解决方案1】:

    我试图查看您的代码,但没有发现任何可疑之处,但您肯定需要将您的 mViewPager2.setOffscreenPageLimit(//Interger Value//) 设置为您的 EmployeeSummaryFragmentHolder

    viewpager2.offscreenPageLimit = 2
    

    【讨论】:

    • 是的,我尝试按照你提到的添加,但仍然面临同样的问题
    • 您使用的是最新的 viewpager2 库吗?其他建议是尝试使用调试和/或降低设置复杂性?也许在您的 EmployeeSummaryFragment createView 中插入一个 Log.D 以便您可以查看片段的创建时间?使用 offscreenPageLimit = 2 时,应在您仍处于第一个时创建第二个和第三个..
    • 还有一点,EmployeeSummaryFragment 上的 onResume 仅在显示片段本身时被调用,所以如果您有任何加载过程,您应该转到 onViewCreated。
    • 非常感谢,我在调试中检查了 1. 当我使用 FragmentStatePagerAdapter 和 ViewPager 时,在所有加载的 Fragment 中都会调用 onResume()。 2. 但是在 FragmentStateAdapter 和 ViewPager2 中,只有当该片段在 UI 上可见时才会调用 onResume()。 3. 我在 onResume() 中有加载过程,现在我已将其移至 onViewCreated(),现在它正在加载,没有任何延迟。接受并支持您的答案和 cmets。
    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 2021-01-12
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    相关资源
    最近更新 更多