提问者:小点点

Android TabLayout ViewPager2更改选项卡而不加载之间的所有选项卡


在我的应用程序中,我有一个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个选项卡,但是对于具有更多选项卡的更复杂的应用程序,它不起作用,所以如果有人知道如何修复它…


共1个答案

匿名用户

要禁用SmashScroll,请使用另一个TabLayoutMediator构造函数:

TabLayoutMediator(tabLayout, viewPager, /*autoRefresh=*/ true, /* smoothScroll= */false
            TabConfigurationStrategy { tab, position ->
                //...
                }
            }).attach()