am having three fragments say A,B and C, one with viewpager that it contains multiple fragments(say fragment B has) in it.
while switching to fragment b will render the fragment viewpager contents after moving to other fragment and back to fragment b, here it will reload the content again.
i just want to stop destroying fragments once it get rendered??
Thanks in Advance.
sample code of adapter:
public class QuestionsSortPagerAdapter extends FragmentPagerAdapter {
int mNumOfTabs;
public QuestionsSortPagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
QuestionsSortByVotes byVotes = new QuestionsSortByVotes();
return byVotes;
case 1:
QuestionsSortByActivity byActivity = new QuestionsSortByActivity();
return byActivity;
case 2:
QuestionsSortByHot byHot = new QuestionsSortByHot();
return byHot;
case 3:
QuestionsSortByDate byDate = new QuestionsSortByDate();
return byDate;
case 4:
QuestionsSortByMonth byMonth = new QuestionsSortByMonth();
return byMonth;
default:
return null;
}
FragmentPagerAdapter will keep all fragments, it just destroy the view of fragment which is invisible to user, for example, if you scroll page from 1 to 2, then the view of page 0 will be destroyed, but the instance of page 0 will still be retained by adapter.
You can change this default behaviour by calling the method ViewPager.setOffscreenPageLimit(int limit), if you set limit to 2, then the view of page 0 will also be retained.
Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state.
Related
As the title suggests, is it possible to replace two fragments while in a third one, for example pressing a button in fragment 3 replaces fragment 1 with fragment 2, while all 3 are inside a ViewPager? For simpler understanding, this is what my PagerAdapter looks like:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
int numberOfTabs;
public SectionsPagerAdapter(FragmentManager fm, int numberOfTabs) {
super(fm);
this.numberOfTabs=numberOfTabs;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch(position){
case 0:
CreateEventFragmentPage1 tab1 = new CreateEventFragmentPage1();
return tab1;
case 1:
CreateEventFragmentPage2 tab2 = new CreateEventFragmentPage2();
return tab2;
case 2:
CreateEventFragmentPage3 tab3 = new CreateEventFragmentPage3();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return numberOfTabs;
}
}
Any and all advice will be highly appreciated.
As this is an adapter FragmentPagerAdapter so there is must be an notifyChanged method or similar
And i suppose it will works as notifyDataSetChanged with Recyclerview
Another reason for this that surrounded fragments of the current are not fully be destroyed
In addition rewrite method getItem(int position) to perform logic of reordering your fragments
Also try out to use an FragmentStatePagerAdapter
I have a PagerAdapter which creates 3 fragments.
In the MainActivity I set the ViewPager like this:
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setOffscreenPageLimit(2);
pager.setAdapter(new PagerAdapter(getSupportFragmentManager()));
the pager.setOffScreenPageLimit(2) is from here https://stackoverflow.com/a/11852707/1662033, to make sure OnViewCreated is called once for each fragment.
Here is my PagerAdapter class:
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Home";
case 1:
return "Live";
case 2:
return "Gallery";
default:
return null;
}
}
#Override
public int getCount() {
return 3;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new HomeFragment();
case 1:
return new LiveFragment();
case 2:
return new GalleryFragment();
default:
return null;
}
}
}
In the current code: all of the fragments's onCreateView, onActivityCreated etc are called once, at the beginning and that's it.
The issue I am having is - in one of the fragments (LiveFragment) I have a custom view which connects to a camera and shows the live stream.
What I want is - to inflate the view of LiveFragment only when the user navigates to the fragment, instead of how its now - its inflated at the beginning with the other fragments.
Is there a way to call onCreateView only when fragment is chosen?
FragmentPagerAdapter creates all the Fragments and has all of them in memory at all time. i.e. All your Fragments are created only once and you can navigate around them.
FragmentStatePagerAdapter creates and has only 3 Fragments (the current Fragment and the left and right Fragments to the current one) in memory at any given time, by default. You cannot reduce that number. However, you can increase the number Fragments in memory by using the viewpager.setOffScreenPageLimit().
Since you have only 3 Fragments, all your 3 fragments are created when the Viewpager is initialised. You can track which Fragment is currently visible on the screen using viewpager.addOnPageChangeListener(). Using this you can change the View of your LiveFragment from dummy one to actual View only when the Fragment is currently visible.
I have an Activity called MainActivity which has a ViewPager and a TabLayout. The ViewPager has 4 (four) fragments that bound there. I have a problem about (maybe) FragmentStatePagerAdapter
I have my code run
public class MainPagerAdapter extends FragmentStatePagerAdapter {
Fragment[] fragments;
public MainPagerAdapter(FragmentManager fm) {
super(fm);
fragments = new Fragment[]{
new FragProfile(),
new FragScore(),
new FragMoney(),
new FragOther()
};
}
#Override
public Fragment getItem(int p) {
Log.w("Fragment", String.valueOf(p));
switch (p){
case 0:
return fragments[0];
case 1:
return fragments[1];
case 2:
return fragments[2];
case 3:
return fragments[3];
default:
return null;
}
}
#Override
public int getCount() {
return 4;
}
}
on first tab, i got this log came out
09-10 20:05:29.683 17034-17034/ampersanda.elsys W/Fragment: 0
09-10 20:05:29.684 17034-17034/ampersanda.elsys W/Fragment: 1
on second
09-10 20:11:03.970 17034-17034/ampersanda.elsys W/Fragment: 2
on third
09-10 20:11:54.534 17034-17034/ampersanda.elsys W/Fragment: 3
but on fourth i got nothing logged, and I back to the third i got this
09-10 20:14:07.373 17034-17034/ampersanda.elsys W/Fragment: 1
Back to second
09-10 20:14:50.241 17034-17034/ampersanda.elsys W/Fragment: 0
and I back to the first, i got nothing logged again
my code doesn't run well, but I got Fragment shows like its switch() but not about code inside it
In your case you should use FragmentPagerAdapter because when you use FragmentStatePagerAdapter the pages may get destroyed, so you will need to recreate them in getItem().
This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment.
How can I avoid a recyclerview to reload when the tabs change?
For example, I have a TabLayout with three Tabs, my ViewPager is:
class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new Tab1Fragment();
case 1:
return new Tab2Fragment();
case 2:
return new Tab3Fragment();
}
return null;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "tab1";
case 1:
return "tab2";
case 2:
return "tab3";
}
return null;
}
}
In the first one, I have a recyclerview, when I change the tabs and back to the first one, the list is reloaded.
There is a way do avoid this reload? Just keep the data loaded.
Android keeps only one fragment on either side of the current fragment in a ViewPager by default. So when you come back to your first tab from the third one, it will recreate the first tab which is what is happening in your case. Here is the documentation.
You need to keep all the Fragments in memory with
viewPager.setOffscreenPageLimit(<(number of fragments in view pager) - 1>) which is 2 in your case.
Of course, as the docs suggest, this number should be kept low especially if its a complex layout.
yourViewPager.setOffscreenPageLimit(2);
So I have a section_home layout that shows a picture. Then I made another layout called section_home_two that shows a different picture. In my code I have a class called HomeFragment for the section_home layout. The second java class is called PreviewsFragment for the section_home_two layout.
Is there anyway you can make HomeFragment swipe horizontally to PreviewsFragment? Is there anyway to merge them?
I would suggest that you use a ViewPager to swipe between the fragments.
Follow the instructions at http://developer.android.com/training/animation/screen-slide.html to get the ViewPager working, and then change the number of pages to 2:
private static final int NUM_PAGES = 2;
And use this PagerAdapter instead of the one in the sample:
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if (position == 0)
return new HomeFragment(); // The ViewPager will show this fragment first
else
return new PreviewsFragment; // and will allow you to swipe to this one and back.
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
This will allow you to swipe horizontally back and forth between the two fragments. if you're using a factory method to create your fragments, use that instead of the return new HomeFragment(); and return new PreviewsFragment(); lines.