5

Hi I have a TabLayout and ViewPager inside a fragment. But I can not slide beetween tab to come to child fragment (Working normally when in Activity but not work in fragment).

Here is my code for Tablayout inside fragment:

@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];
        }

    }

I doubt i have problem with this line:

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

Anyhelp is much appreciate, thanks

Lê Khánh Vinh
  • 2,591
  • 5
  • 31
  • 77

2 Answers2

8

I have done a similar project and here is my code for the fragment :

@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);
        }
    }
Amit Tiwari
  • 3,684
  • 6
  • 33
  • 75
  • Thanks a lot. The solution is we should use getchildFragmentManager. But i still have 1 question that should we put all the executable code inside OncreateView or move some to OnActivityCreated? I want the fragment to only execute if the user slide to that fragment [now they all fragments load at the same time – Lê Khánh Vinh Dec 23 '15 at 12:52
  • you should inflate your views in `onCreateView()` and do whatever processing you want to do in either `onCreateView()` or `onActivityCreated()`. Just remember to do `if(isAdded())` before anywhere you call `getActivity()` – Amit Tiwari Dec 23 '15 at 12:57
  • Im still confuse beetween getContext and getActivity. When to use either one? Do u have an example to make fragment load only when user slide to them? – Lê Khánh Vinh Dec 23 '15 at 13:00
  • try to use `getActivity()`. I am not entirely sure about `getContext()`. What do you mean by load? See views are created in `onCreateView()` and whatever is your code you loading, runs when the corresponding method gets called in which you have put that code. For more information, just see [Fragment Lifecycle](http://developer.android.com/guide/components/fragments.html). – Amit Tiwari Dec 23 '15 at 13:05
  • I mean the code [for ex a Toast message] in child fragment execute right after user click to parent fragment [which has tablayout] when i put child fragment code on OnActivityCreated. Is there any way to make child fragment code only execute when user slide to child fragment? – Lê Khánh Vinh Dec 23 '15 at 13:11
  • I am not fully sure but try putting that code in `onResume`. – Amit Tiwari Dec 23 '15 at 13:16
  • Thanks its working.Use getchildFragmentManager() instead getSupportFragmentManager – madhu527 Jul 10 '17 at 07:34
4

You need to use getChildFragmentManager() in Fragment instead of getFragmentManager().

From getChildFragmentManager() documentation

Return a private FragmentManager for placing and managing Fragments inside of this Fragment.

From getFragmentManager() documentation

Return the FragmentManager for interacting with fragments associated with this fragment's activity.

In simple words,

  • Use getChildFragmentManager() for Child Fragments
  • Use getFragmentManager() for Fragments inside Activity

One can see @this answer for complete code.

Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212