ViewPager не раздувает фрагмент - PullRequest
0 голосов
/ 19 марта 2020

Я использую ViewPager2, FragmentStateAdapter и TabLayout для создания макета с вкладками. Мои TabLayout и ViewPager2 находятся во фрагменте, и у адаптера есть список еще двух фрагментов для вкладок. OnCreateView для каждого из фрагментов никогда не вызывается, когда я использовал отладчик или в операторах журнала. createFragment никогда не вызывается в адаптере вкладок

MainTabHolderFragment: фрагмент

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val tabAdapter = TabAdapter(childFragmentManager, lifecycle)
    tabAdapter.addFragment(AddItemFragment(), "Add Item")
    tabAdapter.addFragment(WishListFragment(), "Wish List")

    binding.viewPager.adapter = tabAdapter
    TabLayoutMediator(
        binding.tabLayout, binding.viewPager,
        TabLayoutMediator.TabConfigurationStrategy { tab, position ->
            tab.text = tabAdapter.getPageTitle(position)
            Timber.d("tab = ${tab.position}, pos = $position")
            binding.viewPager.setCurrentItem(position, true)
        }).attach()
}

TabAdapter

class TabAdapter(fm: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fm, lifecycle) {

    private val fragmentList = mutableListOf<FragmentListItem>()

    override fun createFragment(position: Int) = fragmentList[position].fragment

    override fun getItemCount() = fragmentList.size

    fun addFragment(fragment: Fragment, title: String) {
        fragmentList.add(FragmentListItem(fragment, title))
    }

    fun getPageTitle(position: Int): CharSequence? = fragmentList[position].title


    private data class FragmentListItem(val fragment: Fragment, val title: String)
}

Переменная tab.postion в TabLayoutMediator всегда равна -1, и ViewPager никогда не раздувает фрагменты, в результате чего пустой экран под макетом вкладки. Нужно ли использовать что-то кроме TabLayoutMediator или FragmentStateAdapter?

РЕДАКТИРОВАТЬ: Добавлена ​​информация о том, что createFragment не называется

Ответы [ 2 ]

0 голосов
/ 19 марта 2020

Это слишком просто, добавьте это .. (ВНУТРИ ONCREATEVIEW)

TabLayout tabs = (TabLayout) findViewById(R.id.tabsID);

    tabsID.addTab(tabsID.newTab().setText("Fragment1"));
    tabsID.addTab(tabsID.newTab().setText("Fragment2"));

Теперь у вас уже есть табуляция с именами, теперь создайте метод (ВНЕ ONCREATEVIEW), ВЫ ДОЛЖНЫ СОЗДАТЬ ОДИН ДЛЯ КАЖДОГО TABITEM

public void homeScreen () {
    homeAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_activated_2, homeInformation) {
        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.home_item, parent, false);
            }

            Random rand = new Random();
            int random_number_home = rand.nextInt(10) + 1;

            TextView number_home_list  = (TextView) convertView.findViewById(R.id.number_home_list);
            TextView textViewHome = (TextView) convertView.findViewById(R.id.textViewHome);
            textViewHome.setText(homeInformation[position]);
            number_home_list.setText(Integer.toString(random_number_home));
            return convertView;
        }
    };
    homeList.setAdapter(homeAdapter);
}

этот код отображает ваш просмотр списка со случайными числами, теперь этот код предназначен для вкладок выбора различий .... первый экран, который вы видите при входе в приложение (INSIDE OF) ONCREATEVIEW)

homeScreen();

    final TabLayout.BaseOnTabSelectedListener eventChangeTab = new TabLayout.BaseOnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            if (tab.getText().toString().equals("Resumen")) {
                homeScreen();
            } else if (tab.getText().toString().equals("Datos Abonado")) {
                receiptsScreen();
            } 
        }


        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }


        @Override
        public void onTabReselected(TabLayout.Tab tab) {
            if (tab.getText().toString().equals("Fragment1")) {
                homeScreen();
            } else if (tab.getText().toString().equals("Fragment2")) {
                receiptsScreen();
            } 
        }
    };

    tabsID.addOnTabSelectedListener(eventChangeTab );
0 голосов
/ 19 марта 2020

Мой совет: измените TabAdapterConstructor, используя только параметр Fragment, и используйте в качестве следующего подхода из моего личного проекта:

class YourAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {

    private lateinit var yourList: List<YourListType>

    override fun getItemCount(): Int = yourList.size

    override fun createFragment(position: Int): Fragment =
        YourFragment.instance(yourList[position]) // Only is needed to pass data

    fun setList(yourList: List<YourListType>) {
        this.yourList = yourList
    }
} 

И ViewPager установите в основном фрагменте:

view_pager.adapter = YourAdapter(this).apply{ 
    setList(yourList) 
}

И способ инициации фрагмента:

companion object {
        private const val KEY_YOUR_OBJECT = "KEY_YOUR_OBJECT"

        fun instance(yourObject: YourObject): YourFragment {
            val arguments = Bundle().apply {
                putSerializable(KEY_YOUR_OBJECT, yourObject)
            }

            return YourFragment().apply {
                this.arguments = arguments
            }
        }
}
...