Fragment in TabLayout only load when user slide Android
Solution 1
@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
Solution 2
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
Lê Khánh Vinh
Updated on July 26, 2022Comments
-
Lê Khánh Vinh almost 2 years
Hi I'm making an app with A
fragment
and few childfragment
inside it usingtablayout
andviewpager
. The problem is all my childfragment
(fromTablayout
) always execute (load all the code inside whenever user click the parentfragment
. How to get the childfragment
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
codepublic 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);
-
Kosh over 8 years
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); }
-
Lê Khánh Vinh over 8 yearsthanks for yrs rep. Can u describe a bit more detail. I need to put the above child fragment code on @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); }?
-
Zapnologica over 7 yearsWhen will android just add a callback to the tabView?
-
-
Lê Khánh Vinh over 8 yearsI tried yrs 1st method but does not seem to work. I move all the view code to OnCreateView and left only the method to fetch data getEventDetailRespond(requestQueue); inside @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); } but got null pointer error (I have progressbar.setvisibillity inside the getEventDetailRespond
-
Kosh over 8 yearsinstead of using getChildFragmentManager() could u call getActivity().getSupportFragmentManager() and see if that solve it? however i still encourage you to do some debugging on the answer i did provide.
-
Lê Khánh Vinh over 8 yearsseem to work with simple test Toast message but when I put my fetch data method. return null pointer. here is my method code and the error shown docs.google.com/document/d/…
-
Kosh over 8 yearsyour issue is within this line
ProgressBar.setVisibility(int)
as i mentioned do initialize your views onViewCreated andsetUserVisibleHint
its called beforeonViewCreated
so check against null stuff. -
Lê Khánh Vinh over 8 yearsBut the problem is that I need the progressBar to be visible whenever the method is fetching data from server. when receive the respond from server, the progress bar will be disappear.
-
Lê Khánh Vinh over 8 yearsthanks a lot. So by default if I have 3 fragment, only first 2 fragment will be loaded when user click parent fragment? where to put the viewsetOffscreenPageLimit(int limit) (on parent or child)? can give a bit detail how to implement this?
-
Tin Tran over 8 yearsI made a typo on my answer. already edited. You can call that method on the ViewPager.
-
Lê Khánh Vinh over 8 yearsI seem not to work. I have 2 child fragment. When I put viewpager.setOffscreenPageLimit(0) in my parent OnCreateView. all the code from child fragment 2nd tab is still loaded whenever user click parent fragment
-
Karakuri over 8 years@LêKhánhVinh The minimum off screen page limit is 1.
ViewPager
is going to load stuff off screen so that it's ready when the user starts to scroll. You cannot avoid this. -
Lê Khánh Vinh over 8 yearsthanks a lot. so If I have like 3 tab then the 3rd will not be automatic load when set is default 1?
-
Tin Tran over 8 years@LêKhánhVinh Yes Thats is true. Can I know why you want the system to not preload your fragment ?
-
Lê Khánh Vinh over 8 yearsthat because I want to pass the data get from the first child pass to the 2nd or 3rd child (like update data view based on user change)
-
Harish Vishwakarma about 7 years@LêKhánhVinh: I have a cameraview which gets activated even when am in another tab.