ViewPager2: Can't select particular fragment programmatically

1k views Asked by At

I'm trying to select particular fragment say, 2nd or 3rd fragment in ViewPager2 programmatically. It's not working properly. Sometimes it works, sometimes not. Although It's working for TabLayout every time.

What I have tried:

  1. I have tried using ViewPager2.post like paymentViewpager.post { paymentViewpager.currentItem = 1 }.
  2. Tried adding paymentViewpager.setCurrentItem(tab.position, true) in TabLayoutMediator callback.
  3. I have double checked that I'm calling paymentViewpager.setCurrentItem after adapter is being set.

Code is like below.

In onCreate of an Activity

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()
}

When API response comes after a while, I need to select 2nd Fragment of ViewPager2. Below code executes in that function.

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))
                                    }
                                }
                            }
                        }

I have came across same question here which is don't have accepted answer yet. Any help would be appreciated.

1

There are 1 answers

10
Zain On

I came across this with ViewPager2, for me the reason was enabling the smoothScroll (second parameter in setCurrentItem) as enabling it makes the ViewPager goes to a wrong page

So the fix was to disable it:

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