В моем приложении у меня есть ViewPager2
и TabLayout
. Приложение состоит из 4 вкладок. Третий динамически загружает фрагмент списка.
У меня проблема с открытием 4-й вкладки, но только когда я не открыл 3-й ранее. Например, это вызовет sh:
Открыть приложение, показать первую вкладку. Нажмите на 4-й вкладке. => Приложение создаст sh со следующей ошибкой:
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}
Но если я сделаю следующее:
Откройте приложение, откройте 1-ю вкладку. Нажмите на 3-й вкладке. Нажмите на 4-й вкладке. => Приложение не взломает sh.
Похоже, что когда я меняю вкладку, она «пролистывает» все вкладки между текущей вкладкой и нажатием, что вызывает фрагменты начать инициализацию.
Вот код 3-й фрагмент :
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
}
}
}
My ListFragment :
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
}
}
И действия , которое содержит пейджер представления :
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 или, если нет, как я могу предотвратить эту ошибку?
РЕДАКТИРОВАТЬ / ВРЕМЕННОЕ РЕШЕНИЕ:
Хорошо, так Я нашел обходной путь для этой ошибки. Вместо того, чтобы использовать комбинацию ViewPager2 и TabLayout, я теперь использую BottomNavigation для того же результата, но без эффекта смахивания. В моем случае это работает, потому что мне нужны только 4 вкладки, но для более сложных приложений с большим количеством вкладок это не сработает, поэтому, если кто-нибудь знает, как это исправить ...