TabLayout с ViewPager не работает внутри фрагмента Android

Привет, у меня есть TabLayout и ViewPager внутри фрагмента. Но я не могу скользить между вкладками, чтобы перейти к дочернему фрагменту (нормально работает в действии, но не работает во фрагменте).

Вот мой код для Tablayout внутри фрагмента:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View inflateView = inflater.inflate(R.layout.fragment_assign_beacon_to_event, container, false);

        //Viewpager and TabLayout
        viewPager = (ViewPager)inflateView.findViewById(R.id.viewPager);
        viewPager.setAdapter(new CustomAdapter(getFragmentManager(), getContext()));

        tabLayout = (TabLayout)inflateView.findViewById(R.id.tabLayout);


        // Inflate the layout for this fragment
        return inflateView;
    }

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

    tabLayout.post(new Runnable() {
                @Override
                public void run() {
                    tabLayout.setupWithViewPager(viewPager);

            }
        });

        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }
        });

Any here is my Custom Adapter class

private class CustomAdapter extends FragmentPagerAdapter {

        private String fragments[] = {"Assign Event", "Manage Event"};

        public CustomAdapter(FragmentManager supportFragmentManager, Context applicationContext) {
            super(supportFragmentManager);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
//                    return new AssignEventToBeacon();
                    return new Test1();
                case 1:
                    return new ManageEventAssigned();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return fragments.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return fragments[position];
        }

    }

Я сомневаюсь, что у меня проблема с этой строкой:

viewPager.setAdapter(new CustomAdapter(getFragmentManager(), getContext()));

Любая помощь очень ценится, спасибо


person Lê Khánh Vinh    schedule 23.12.2015    source источник
comment
пожалуйста, попробуйте как viewPager.setAdapter(новый CustomAdapter(getSupportFragmentManager(), getContext())); // getSupportFragmentManager() или getChildFragmentManager()   -  person Mr Robot    schedule 23.12.2015
comment
Посмотрите, в этом вопросе есть все, что вы хотите. stackoverflow.com/q/34015117/2404262   -  person Anshul Tyagi    schedule 23.12.2015
comment
Спасибо за ваш ответ. Я пробовал оба, но не работал. В любом случае, чтобы tablayout и ViewPager работали во фрагменте так же, как и в действии?   -  person Lê Khánh Vinh    schedule 23.12.2015
comment
кто-нибудь знает, как заставить tablayout и viewpager работать внутри фрагмента?   -  person Lê Khánh Vinh    schedule 23.12.2015


Ответы (2)


Я сделал аналогичный проект, и вот мой код для фрагмента:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.outer_fragment, container, false);
        setHasOptionsMenu(true);

        ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
        if (viewPager != null) {
            setupViewPager(viewPager);
        }

        Log.v("Layout","Tabs");
        TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
        tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FFFFFF"));
        tabLayout.setTabTextColors(Color.parseColor("#707070"), Color.parseColor("#FFFFFF"));
        assert viewPager != null;
        tabLayout.setupWithViewPager(viewPager);

        return view;
    }

private void setupViewPager(ViewPager viewPager) {
        Adapter adapter = new Adapter(getChildFragmentManager());
        adapter.addFragment(new Tab1Fragment(), "PHOTOS");
        adapter.addFragment(new Tab2Fragment(), "HI-FIVES");
        viewPager.setAdapter(adapter);
    }


static class Adapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragments = new ArrayList<>();
        private final List<String> mFragmentTitles = new ArrayList<>();

        public Adapter(FragmentManager fm) {
            super(fm);
        }

        public void addFragment(Fragment fragment, String title) {
            mFragments.add(fragment);
            mFragmentTitles.add(title);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitles.get(position);
        }
    }
person Amit Tiwari    schedule 23.12.2015
comment
Большое спасибо. Решение состоит в том, что мы должны использовать getchildFragmentManager. Но у меня все еще есть 1 вопрос: мы должны поместить весь исполняемый код в OncreateView или переместить часть в OnActivityCreated? Я хочу, чтобы фрагмент выполнялся только в том случае, если пользователь переходит к этому фрагменту [теперь все фрагменты загружаются одновременно - person Lê Khánh Vinh; 23.12.2015
comment
вы должны раздувать свои представления в onCreateView() и выполнять любую обработку, которую вы хотите сделать, либо в onCreateView(), либо в onActivityCreated(). Просто не забудьте сделать if(isAdded()) перед любым вызовом getActivity(). - person Amit Tiwari; 23.12.2015
comment
Я все еще путаюсь между getContext и getActivity. Когда использовать любой из них? У вас есть пример загрузки фрагмента только тогда, когда пользователь переходит к ним? - person Lê Khánh Vinh; 23.12.2015
comment
попробуйте использовать getActivity(). Я не совсем уверен насчет getContext(). Что вы имеете в виду под нагрузкой? См. представления, созданные в onCreateView(), и независимо от того, какой код вы загружаете, запускается, когда вызывается соответствующий метод, в который вы поместили этот код. Дополнительные сведения см. в разделе Жизненный цикл фрагмента. - person Amit Tiwari; 23.12.2015
comment
Я имею в виду, что код [например, сообщение Toast] в дочернем фрагменте выполняется сразу после того, как пользователь щелкает родительский фрагмент [который имеет табличку], когда я помещаю код дочернего фрагмента в OnActivityCreated. Есть ли способ заставить код дочернего фрагмента выполняться только тогда, когда пользователь переходит к дочернему фрагменту? - person Lê Khánh Vinh; 23.12.2015
comment
Я не совсем уверен, но попробуйте поместить этот код в onResume. - person Amit Tiwari; 23.12.2015
comment
Спасибо за работу. Используйте getchildFragmentManager() вместо getSupportFragmentManager - person madhu527; 10.07.2017

Вам нужно использовать getChildFragmentManager() во фрагменте вместо getFragmentManager().

Из документации getChildFragmentManager()

Вернуть частный FragmentManager для размещения и управления фрагментами внутри этого фрагмента.

Из документации getFragmentManager()

Верните FragmentManager для взаимодействия с фрагментами, связанными с активностью этого фрагмента.

Простыми словами,

  • Используйте getChildFragmentManager() для дочерних фрагментов
  • Используйте getFragmentManager() для фрагментов внутри Activity

Полный код можно увидеть в @this answer.

person Khemraj Sharma    schedule 16.11.2018