来自Jeel Vankhede的答案被标记为一个解决方案并付诸实施。为供将来参考,解决方案代码将粘贴在下面,以显示ViewPager和适配器如何成功独立于ViewModel的细节:
查看寻呼机:
注意,我们现在有了一个接口对象。滑动ViewPager时,如果没有接口对象,则会引发异常。
//Overriding default touch events and swapping x/y coordinates prior to handling
class VerticalTimerViewPager(context: Context, attributeSet: AttributeSet): ViewPager(context, attributeSet){
var timerViewPagerEventListener: TimerViewPagerEvent? = null
init {
setPageTransformer(true, VerticalPageTransformer())
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
ev ?: return false
val intercepted = super.onInterceptTouchEvent(swapXYOnMotionEvent(ev))
swapXYOnMotionEvent(ev)
return intercepted
}
override fun onTouchEvent(ev: MotionEvent?): Boolean {
timerViewPagerEventListener ?: throwInterfaceExeption()
when(ev?.action){
MotionEvent.ACTION_DOWN -> timerViewPagerEventListener?.onViewPagerSwipeDown()
MotionEvent.ACTION_UP -> timerViewPagerEventListener?.onViewPagerSwipeUp()
}
return super.onTouchEvent(swapXYOnMotionEvent(ev ?: return false))
}
private fun throwInterfaceExeption():Boolean {
throw RuntimeException("${this.javaClass.simpleName}: Parent Activity must implement TimerViewPagerEvent interface" )
}
private fun swapXYOnMotionEvent(motionEvent: MotionEvent): MotionEvent{
with(motionEvent){
val newX = (y/height)*width
val newY = (x/width) * height
setLocation(newX, newY)
}
return motionEvent
}
interface TimerViewPagerEvent{
fun onViewPagerSwipeUp()
fun onViewPagerSwipeDown()
}
}
现在获取对象列表(本例中为计时器)
class TimerSlidePagerAdapter(fragmentManager: FragmentManager, private val timers: List<TimerEntity>?):
FragmentStatePagerAdapter(fragmentManager){
override fun getItem(position: Int): Fragment {
if (count > 0) {
return makeTimerFragment(position)
}
return NoDataFragment()
}
override fun getCount(): Int = timers?.size ?: 0
//Internal Functions
private fun makeTimerFragment(position: Int): Fragment {
timers ?: return NoDataFragment()
val timeInMS = timers[position].timeInMS
return if (timeInMS > 0) {
TimerFragment.newInstance(timeInMS)
} else {
NoDataFragment()
}
}
}
活动实施:
private fun setupPagerAdapter() {
val pagerAdapter = TimerSlidePagerAdapter(
fragmentManager = supportFragmentManager,
timers = viewModel?.timers?.value)
with(pager){
adapter = pagerAdapter
timerViewPagerEventListener = this@MainActivity
}
}
private fun observeTimers(){
viewModel.timers.observe(this, Observer {timerList->
timerList ?: Log.e(this.javaClass.simpleName, "List of timers is null")
.also {return@Observer}
setupPagerAdapter()
})
}