Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment in TabLayout only load when user slide Android

Hi I'm making an app with A fragment and few child fragment inside it using tablayout and viewpager. The problem is all my child fragment (from Tablayout) always execute (load all the code inside whenever user click the parent fragment. How to get the child fragment only load whenever the the user slide to it (for example I have 2 tab, content in tab 2 only load when user slide to tab 2)

Here is my parent fragment code

public class ManageEventFragment extends Fragment {


    public ManageEventFragment() {
        // Required empty public constructor
    }


    TabLayout tabLayout;
    ViewPager viewPager;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View viewFragment = inflater.inflate(R.layout.fragment_manage_event, container, false);

        viewPager = (ViewPager) viewFragment.findViewById(R.id.viewPager);

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

        viewPager.setAdapter(new CustomAdapter(getChildFragmentManager(), getContext()));
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        return viewFragment;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        //        tabLayout.setupWithViewPager(viewPager);
        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());
            }
        });

        if (ViewCompat.isLaidOut(tabLayout)) {
            tabLayout.setupWithViewPager(viewPager);
        } else {
            tabLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    tabLayout.setupWithViewPager(viewPager);
                    tabLayout.removeOnLayoutChangeListener(this);
                }
            });
        }

        super.onActivityCreated(savedInstanceState);

    }


    //TabLayout and ViewPager class
    private class CustomAdapter extends FragmentPagerAdapter {

        private String fragments[] = {"Edit Event", "Create Event"};

        public CustomAdapter(FragmentManager fragmentManager, Context context) {
            super(fragmentManager);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new EditEventFragment();
                case 1:
                    return new CreateEventFragment();
                default:
                    return null;
            }
        }

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

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

    }

}

And my child fragment code. I want these code only execute whenever the user slide to the child tab. Any help is much appreciate, Thanks

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

        //Initializing our listEvents list
        listEvents = new ArrayList();

        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        adapter = new EventAdapterEdit(getContext(),listEvents);
        recyclerView.setAdapter(adapter);


        requestQueue = Volley.newRequestQueue(getContext());

        adapter = new EventAdapterEdit(getContext(),listEvents);
        recyclerView.setAdapter(adapter);

        getEventDetailRespond(requestQueue);
like image 981
Lê Khánh Vinh Avatar asked Dec 28 '15 01:12

Lê Khánh Vinh


2 Answers

The Viewpager by default loads the adjacent fragment to ensure make the app smooth, so that when the user swipe to the fragments (already loaded) it is there. To change is default behavior, use viewpager.setOffscreenPageLimit(int limit) where limit is how many fragment next to the one you are on will be preloaded. Hope this helps

like image 34
Tin Tran Avatar answered Oct 22 '22 05:10

Tin Tran


@Override public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
}

you could use above method within your fragment that is within your ViewPager Adapter

if(isVisibleToUser){//dosomething when the fragment is visible}
else{//dosomething else.}

be aware to do not initialize views there or anything rather, init your views within onViewCreated and call the method that you wanna execute on setUserVisibleHint. another ugly way is to add a scroll listener to your ViewPager and get the current item position and trigger an action that is within the fragment. to get the fragment from the ViewPager Adapter you can do such :

 MyFragment frag = (MyFragment) pager.getAdapter().instantiateItem(pager, position);

then you could call a method that is within MyFragment

like image 178
Kosh Avatar answered Oct 22 '22 05:10

Kosh