在我的应用程序中,我有一个ViewPager2
和一个TabLayout
。该应用程序由4个选项卡组成。第三个动态加载列表片段。
我在打开第4个选项卡时遇到问题,但只是在我之前没有打开第3个选项卡时。例如,这将崩溃:
打开应用程序,显示第一个选项卡。单击第四个选项卡。=
java.lang.IllegalArgumentException: No view found for id 0x7f080105 (my.package:id/root_frame) for fragment ListFragment{6190d6d (6304bfad-1db2-464d-a524-7e3450243bcc) id=0x7f080105}
但如果我按照以下方式进行:
打开应用程序,显示第一个选项卡。单击第三个选项卡。单击第四个选项卡。=
看起来当我更改选项卡时,它会“滑动”当前选项卡和单击的选项卡之间的所有选项卡,导致片段开始初始化。
这是第三个片段的代码:
class ListRootFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.list_root_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val transaction = fragmentManager!!.beginTransaction()
transaction.replace(R.id.root_frame, ListFragment.newInstance())
transaction.commit()
}
companion object {
fun newInstance(): ListRootFragment {
val fragment = ListRootFragment()
val args = Bundle()
fragment.arguments = args
return fragment
}
}
}
我的列表片段:
class ListFragment : Fragment() {
lateinit var globalData: GlobalData
private lateinit var listView: ListView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
globalData = (this.activity as ContentActivity).globalData
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View { // Inflate the layout for this fragment
val rootView: View =
inflater.inflate(R.layout.fragment_list, container, false)
listView = rootView.findViewById<ListView>(R.id.categoriesList)
val categoriesList = globalData.getCategories()
val adapter = this.getActivity()?.applicationContext?.let { CategoryAdapter(it, categoriesList) }
listView.adapter = adapter
listView.setOnItemClickListener { _, _, position, _ ->
// ...
}
return rootView
}
companion object {
fun newInstance(): ListFragment {
val fragment = ListFragment()
val args = Bundle()
fragment.arguments = args
return fragment
}
}
}
这是我的ViewPagerAdapter的代码:
class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
override fun createFragment(position: Int): Fragment {
return when(position){
0 -> HomeFragment.newInstance()
1 -> MapViewFragment.newInstance()
2 -> ListRootFragment.newInstance()
3 -> MoreFragment.newInstance()
else -> HomeFragment.newInstance()
}
}
override fun getItemCount(): Int {
return TAB_COUNT
}
companion object {
private const val TAB_COUNT = 4
}
}
以及包含视图分页器的Activity:
class ContentActivity : AppCompatActivity() {
lateinit var globalData: GlobalData
lateinit var viewPager: ViewPager2
lateinit var tabLayout: TabLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_content)
globalData = applicationContext as GlobalData
viewPager = findViewById(R.id.pager)
tabLayout = findViewById(R.id.tab_layout)
viewPager.setAdapter(createCardAdapter())
viewPager.isUserInputEnabled = false
TabLayoutMediator(tabLayout, viewPager,
TabConfigurationStrategy { tab, position ->
when (position) {
0 -> tab.text = "Home"
1 -> tab.text = "Map"
2 -> tab.text = "List"
3 -> tab.text = "More"
else -> tab.text = "undefined"
}
}).attach()
}
private fun createCardAdapter(): ViewPagerAdapter? {
return ViewPagerAdapter(this)
}
}
有没有办法防止标签2 3在从1到4时加载,或者,如果没有,我如何防止这个错误?
编辑/工作范围:
好的,所以我找到了这个bug的解决方法。我现在没有使用ViewPager2和TabLayout的组合,而是使用了一个底部导航来获得完全相同的结果,但是没有滑动效果。在我的情况下,它可以工作,因为我只需要4个选项卡,但是对于具有更多选项卡的更复杂的应用程序,它不起作用,所以如果有人知道如何修复它…
要禁用SmashScroll
,请使用另一个TabLayoutMediator
构造函数:
TabLayoutMediator(tabLayout, viewPager, /*autoRefresh=*/ true, /* smoothScroll= */false
TabConfigurationStrategy { tab, position ->
//...
}
}).attach()