Android TabLayout + ViewPager2 изменить вкладку без загрузки всех вкладок между - PullRequest
0 голосов
/ 09 февраля 2020

В моем приложении у меня есть 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 вкладки, но для более сложных приложений с большим количеством вкладок это не сработает, поэтому, если кто-нибудь знает, как это исправить ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...