问题描述
ViewPager2 由 IllegalStateException 引起 FragmentManager 已经在执行事务
复制崩溃:旋转屏幕时
如何修复 Viewpager2 FragmentManager 已经在执行事务?
完整源代码: https://github.com/stevdza-san/ViewPager2-with-Navigation-Component-TestApp
ViewPagerFragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.test.zigmaster.databinding.FragmentViewPagerBinding
class ViewPagerFragment : Fragment() {
var binding : FragmentViewPagerBinding?= null
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
// val view = inflater.inflate(R.layout.fragment_view_pager,container,false)
binding = FragmentViewPagerBinding.inflate(inflater)
val fragmentList = arraylistof<Fragment>(
FirstScreen(),SecondScreen(),ThirdScreen()
)
val adapter = ViewPagerAdapter(
fragmentList,requireActivity().supportFragmentManager,lifecycle
)
binding!!.viewPager.adapter = adapter
return binding!!.root
}
override fun onDestroyView() {
super.onDestroyView()
binding=null
}
}
ViewPagerAdapter.kt
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
class ViewPagerAdapter(
list: ArrayList<Fragment>,fm: FragmentManager,lifecycle: Lifecycle
) : FragmentStateAdapter(fm,lifecycle) {
private val fragmentList = list
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
return fragmentList[position]
}
}
fragment_view_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.app_intro.ViewPagerFragment">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
FirstScreen.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.test.zigmaster.R
import com.test.zigmaster.databinding.FragmentFirstScreenBinding
class FirstScreen : Fragment() {
private var binding : FragmentFirstScreenBinding?= null
override fun onCreateView(
inflater: LayoutInflater,savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentFirstScreenBinding.inflate(inflater)
val viewPager = activity?.findViewById<ViewPager2>(R.id.viewPager)
binding!!.next.setonClickListener {
viewPager?.currentItem = 1
}
return binding!!.root
}
override fun onDestroyView() {
super.onDestroyView()
binding=null
}
解决方法
将 view.viewPager.adapter = adapter
更改为
Handler(Looper.getMainLooper()).post {
view.viewPager.adapter = adapter
}