ViewPager2 переходит на первую страницу при изменении дочернего элемента

У меня есть ViewPager2 с FragmentStateAdapter и нескончаемым количеством страниц; каждый дочерний элемент Fragment имеет внутри recyclerView и общую модель просмотра для всех фрагментов.

Я слушаю живые данные общей модели просмотра (потому что все фрагменты слушают одни и те же живые данные); когда срабатывает liveata, я обновляю recyclerView внутри каждого фрагмента.

Однако, когда происходит обновление recyclerview, ViewPager автоматически переходит на первую страницу, полностью разрушая взаимодействие с пользователем.

Есть ли способ не вернуться на первую страницу при изменении данных?

# ОБНОВЛЕНИЕ 02.03.2021

Мой подкласс FragmentStateAdapter:

class IngredientsViewPagerAdapter(fragment: Fragment, private val ingredientType: Int) :
FragmentStateAdapter(fragment) {

private var numberOfPages : Int = 0

fun setNumberOfPages(numberOfPages : Int){
    if (this.numberOfPages != numberOfPages) {
        this.numberOfPages = numberOfPages
        notifyDataSetChanged()
    }
}


override fun getItemCount(): Int {
    return numberOfPages
}

override fun createFragment(position: Int): Fragment {
    return CustomDrinkIngredientsPagerFragment.newInstance(position, ingredientType)
}}

Использованный фрагмент:

class CustomDrinkIngredientsPagerFragment : Fragment(R.layout.view_pager_standard_drinks),
IngredientsListAdapter.IngredientListAdapterInterface{

private val customDrinkViewModel : CustomDrinkViewModel by activityViewModels()
private lateinit var rvIngredients : RecyclerView
private val ingredientListAdapter = IngredientsListAdapter(emptyList(), this@CustomDrinkIngredientsPagerFragment)
private val position by lazy {
    requireArguments().getInt("position")
}
private val ingredientType by lazy {
    requireArguments().getInt("ingredientType")
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    rvIngredients = view.findViewById(R.id.list_recycler_view)
    rvIngredients.apply {
        layoutManager =
            GridLayoutManager(requireContext(), 4, GridLayoutManager.VERTICAL, false)
        adapter = ingredientListAdapter
    }
    customDrinkViewModel.ingredients.observe(viewLifecycleOwner) {
        ingredientListAdapter.submitList(it[ingredientType]!![position])
        Log.d("ROB", "Observed ingredients iType:${ingredientType} position:${position}")
    }
}

override fun onIngredientSelected(ingredient: Ingredient) {
    customDrinkViewModel.addIngredient(ingredient)
}

companion object {
    @JvmStatic
    fun newInstance( position : Int, ingredientType : Int): CustomDrinkIngredientsPagerFragment{
        val args = Bundle()
        args.putInt("position", position)
        args.putInt("ingredientType", ingredientType)
        val fragment = CustomDrinkIngredientsPagerFragment()
        fragment.arguments = args
        return fragment
    }
}}

person martirius    schedule 01.03.2021    source источник
comment
Любой фрагмент кода поможет.   -  person Android Killer    schedule 01.03.2021
comment
FragmentStateAdapter основан на RecyclerView.Adapter, возможно, некоторое обновление данных сбрасывает представление (прокручивается в начало). Но, как сказал Android Killer, некоторый код будет полезен.   -  person SadClown    schedule 01.03.2021
comment
@AndroidKiller обновлен кодом, который используется в настоящее время   -  person martirius    schedule 02.03.2021


Ответы (1)


Я обнаружил проблему: это был родительский ViewPager (из ViewPager выше). Я думал, что проблема во втором ViewPager, а не в родительском.

Фактическая структура была такой: ViewPager - ›ViewPager -› Фрагмент с RecyclerView.

При изменении второго дочернего элемента ViewPager первый ViewPager получает уведомление об изменении дочернего элемента и автоматически запускается notifyDatasetChanged (переход на страницу 0).

person martirius    schedule 03.03.2021