ViewPager2:以编程方式选择特定片段

Posted

技术标签:

【中文标题】ViewPager2:以编程方式选择特定片段【英文标题】:ViewPager2: Select particular fragment programmatically 【发布时间】:2021-07-20 19:10:59 【问题描述】:

我正在尝试以编程方式选择特定片段,例如 ViewPager2 中的第二个或第三个片段。它不能正常工作。有时有效,有时无效。虽然它每次都适用于 TabLayout。

我尝试过的:

    我已尝试使用 ViewPager2.post,例如 paymentViewpager.post paymentViewpager.currentItem = 1 。 尝试在TabLayoutMediator 回调中添加paymentViewpager.setCurrentItem(tab.position, true)。 在设置适配器后,我再次确认我正在调用paymentViewpager.setCurrentItem

代码如下。

在一个Activity的onCreate中

if (!isGuestUser) 
        getPaymentMethod()
        viewModel.getMyProfile()
     else 
        val adapter = SecureCheckoutPaymentSelectionAdapter(
                activity = this,
                callback = this,
                gPayCallback = this,
                paypalCallBack = this,
                cardPaymentList = arrayListOf(),
                gPayPaymentDetail = arrayListOf(),
                payPalPaymentDetail = arrayListOf(),
                isPaymentMethodPresent = false,
                itemsCount = THREE,
                userType = userType,
                isGuestUser
        )
        binding.includeSecureCheckoutPaymentDetails.paymentViewpager.adapter = adapter

        initTabLayout()
    

private fun initTabLayout() 
    TabLayoutMediator(binding.includeSecureCheckoutPaymentDetails.paymentTab, binding.includeSecureCheckoutPaymentDetails.paymentViewpager)  tab, position ->
        val view = DataBindingUtil.inflate<LayoutTabImageBinding>(LayoutInflater.from(this), R.layout.layout_tab_image, tab.view, true)

        when (position) 
            0 -> 
                view.icon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.card_payment))
            
            1 -> 
                view.icon.setBackgroundResource(R.drawable.google_pay_primary_logo)
            
            else -> 
                view.icon.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.paypal_card))
            
        
        tab.customView = view.root
        binding.includeSecureCheckoutPaymentDetails.paymentViewpager.setCurrentItem(tab.position, true)
    .attach()

当 API 响应一段时间后,我需要选择 ViewPager2 的 2nd Fragment。下面的代码在该函数中执行。

val adapter = SecureCheckoutPaymentSelectionAdapter(
                                activity = this,
                                callback = this,
                                gPayCallback = this,
                                paypalCallBack = this,
                                cardPaymentList = if (userType == PERSONAL_USER_TYPE) paymentSavedResponse.personalCards as ArrayList<PaymentMethod>
                                else paymentSavedResponse.businessCards as ArrayList<PaymentMethod>,
                                gPayPaymentDetail = paymentSavedResponse.googlePay as ArrayList<GooglePay>,
                                payPalPaymentDetail = paymentSavedResponse.paypalAccount,
                                isPaymentMethodPresent = paymentSavedResponse.paymentMethodPresent,
                                itemsCount = THREE,
                                userType = userType,
                                isGuestUser
                        )
                        binding.includeSecureCheckoutPaymentDetails.paymentViewpager.adapter = adapter

                        initTabLayout()
                        setViewPagerClick()

                        if (paymentSavedResponse.latestPaymentDetails?.paymentMethodPresent == true) 
                            Log.e("mk", "in paymentMethodPresent == true...")
                            when 
                                paymentSavedResponse.latestPaymentDetails.paymentMethod.size > ZERO -> 
                                    Log.e("mk", "in card...")
                                    binding.includeSecureCheckoutPaymentDetails.apply 
                                        paymentViewpager.currentItem = ZERO
                                        //paymentTab.selectTab(paymentTab.getTabAt(ZERO))
                                    
                                
                                paymentSavedResponse.latestPaymentDetails.googlePay.size > ZERO -> 
                                    Log.e("mk", "in GPay...")
                                    binding.includeSecureCheckoutPaymentDetails.apply 
                                        paymentViewpager.currentItem = ONE
                                        //paymentTab.selectTab(paymentTab.getTabAt(ONE))
                                    
                                
                                else -> 
                                    Log.e("mk", "in Else...")
                                    binding.includeSecureCheckoutPaymentDetails.apply 
                                        paymentViewpager.currentItem = TWO
                                        //paymentTab.selectTab(paymentTab.getTabAt(TWO))
                                    
                                
                            
                        

我遇到了同样的问题here,它还没有被接受的答案。任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我在ViewPager2 中遇到了这个问题,对我来说,原因是启用了 smoothScroll(setCurrentItem 中的第二个参数),因为启用它会使ViewPager 转到错误的页面

所以解决方法是禁用它:

binding.includeSecureCheckoutPaymentDetails.paymentViewpager.setCurrentItem(tab.position, false)

【讨论】:

好的。如果您需要我方面的任何进一步信息,请告诉我。 你可以试试paymentViewpager.postDelayed() 有一些延迟 我试过了,不过让我再试一次。 @Zain 我尝试过 500 和 1000 毫秒,它很少不起作用。大多数时候它正在工作。这是一个适当的解决方案吗? @Zain 不,它应该是最大的 100 毫秒或 200 毫秒,大于这不应该是正确的解决方案,我们只需要确保在主线程循环中的任何其他 UI 事物上都没有挂起。 .. 一定有其他原因造成这种情况

以上是关于ViewPager2:以编程方式选择特定片段的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法以编程方式使用kotlin更改片段中的文本颜色?

ViewPager2 selectCurrentItem - 选择选项卡,但在此选项卡内放置错误的片段

在 TabLayout 和 ViewPager2 中执行异步任务后更新具有相同布局的多个片段

从 Viewpager2 片段访问父片段函数

ViewPager2 无法动态添加删除片段

如何在android中以编程方式在片段之间导航?