Я изо всех сил пытался выяснить, как проверить фрагменты внутри ViewPager2
в моем классе Test ... Цель моего теста - убедиться, что ViewPager2
имеет ожидаемые фрагменты.
Вот как я его настраивал (реализация):
// Implementation class
// fragmentViewPager is my ViewPager2
...
fun setupFragments(fragments:List<Fragment>) {
fragmentCount = fragments.size
fragmentViewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL
fragmentViewPager.adapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
}
fragmentViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
lastInteractedFragmentIndex = position
}
})
}
...
Поскольку я создаю его, передавая FragmentStateAdapter
, я ожидал, что смогу вытащить тот же объект, чтобы я мог посмотретьдля классов Fragments для моего модульного теста, но адаптер ViewPager2 имеет тип RecyclerView.Adapter<RecyclerView.ViewHolder>
На самом деле мне удалось получить правильное количество фрагментов, но это все.
// Inside Test Class attempt #1
...
val adapter:RecyclerView.Adapter<RecyclerView.ViewHolder> = fragmentViewPager.adapter!!
assertEquals(3, adapter.itemCount)
...
Моя вторая попытка состояла в получении отображаемых фрагментов с помощью supportFragmentManager
, который всегда возвращает фрагмент, отображаемый в данный момент ViewPager2
(Контекст: я показываю 1 фрагмент за раз)
Тогда я былдумая, что, возможно, я смогу провести пальцем влево по viewpager2
, чтобы следующий фрагмент стал видимым, чтобы я мог повторить тот же трюк:
// Inside Test Class attempt #2
...
var myFragments = activity!!.supportFragmentManager.fragments
assertTrue(myFragments[0] is MyFirstFragment) // This assertion is correct
val downEvent = MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis() + 100,
MotionEvent.ACTION_DOWN,
150f,
150f,
0
)
val upEvent = MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis() + 100,
MotionEvent.ACTION_UP,
0f,
150f,
0
)
// I tried desperately in both activity and viewPager2 separately and both as once like this:
activity!!.dispatchTouchEvent(downEvent)
activity!!.dispatchTouchEvent(upEvent)
fragmentViewPager!!.dispatchTouchEvent(downEvent)
fragmentViewPager.dispatchTouchEvent(upEvent)
// If swipe was performed technically after pulling the fragments again using supportFragmentManager, the first one (and only one) should be the next fragment in the viewPager2
myFragments = activity!!.supportFragmentManager.fragments
assertTrue(myFragments[0] is MySecondFragment) // Wrong assertion, swipe did not work
И моя последняя и самая простая попытка была сделана jПросто измените выбранный элемент, как в старомодном viewPager (one):
// Inside Test Class attempt #3
...
fragmentViewPager.setCurrentItem(1) // Trying to change to position 1
...
Поступая так, я могу попытаться использовать ту же тактику в попытке №2, используя supportFragmentManager
. К сожалению, делая это, тест полностью останавливается и никогда не заканчивается
Я также безуспешно пытаюсь поиграть с requestDisallowInterceptTouchEvent
методом ViewPager2
.