I followed this tutorial to create an app with four tabs in the action bar [tab1][tab2][tab3][tab4].
When I change from a tab to the nearest one, the destination tab doesn t refresh for example from 1->2 , 3->4 or 3->2, but the problem is when I change from 1->3 or 4, 2->4 ...(a far tab) the destination tab refresh, how can I disable this ?
In the tutorial code, a new instance of fragment is getting generated every time it went to background.
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
}
Instead of it create fragment at the top level i,e create once you start the class.
public class TabsPagerAdapter extends FragmentPagerAdapter {
TopRatedFragment frag1;
GamesFragment frag2;
MoviesFragment frag3;
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
if(frag1 == null)
frag1 = new TopRatedFragment();
return frag1;
case 1:
//repeat same here
case 2:
//repeat same here
}
By this, if an instance of fragment already exist, then it will return that instance instead of new one.
Related
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.
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);
I'm making a very simple app using the ViewPager. I would like to be able to start at a custom position when the getItem method is called. Below is my current code.
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment fragment1 = new Fragment1();
return fragment1;
case 1:
Fragment fragment2 = new Fragment2();
return fragment2;
case 2:
Fragment fragment3 = new Fragment3();
return fragment3;
default:
return null;
}
I was wondering how it would be possible to start at position 1 instead of 0 when the getItem method is called and then to be able to swipe to position 0 or 2 from position 1.
Why don't you simply set selected item to 1 after setting adapter?
mPager.setCurrentItem(1);
Ok so,I'm new to Android programing and I have a question. I have a swipeview similar to the one in the Play Store,and I want each tab to contain a different listview fragment. I have 2 fragments ,one called LP and other PL ,lets say. How to I edit this part of code so it uses my fragments ?
#Override
public Fragment getItem(int position) {
Fragment fragment = new Fragment();
switch (position) {
case 0:
return fragment = new Fragment1();
case 1:
return fragment = new Fragment2();
case 2:
return fragment = new Fragment3();
default:
break;
}
return fragment;
EDIT : So after listening to the advice given,it still doesent work. :-?? I have 2 separate java files for my fragments and it doesent seem to work unless i copy the classes and put them inside the main activity...I may be missing something ,so please feel free to point out any posibility
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment fragment = new Fragment1();
return fragment;
case 1:
Fragment fragment = new Fragment2();
return fragment;
case 2:
ListFragment fragment = new Fragment3();//for list fragments
return fragment;
default:
break;
}
return fragment;
You could use something like this:
#Override
public Fragment getItem(int position) {
Fragment result;
switch (position) {
case 0:
result = new LPFragment();
case 1:
result = new PLFragment();
default:
result = new DefaultFragment();
}
return result
}
You just need to return an instance of whatever fragment you want for each case in the switch.
If the PL and LP classes extends from Fragment then it's fine (though you may have some need to cast them elsewhere in the code as the function returns Fragment and not your own class types)
So I'm trying to create a swipe tab view in my app. But the problem I'm having is that my fragments need to be FragmentActivity becuase they have listview inside them.
So I think this is where I'm getting my error:
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
case 3:
//Other fragment activity
return new OtherFragment();
}
return null;
}
This needs to be:
public FragmentActivity getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
case 3:
//Other fragment activity
return new OtherFragment();
}
return null;
}
But I keep getting errors on this line:
public FragmentActivity getItem(int index) {
Error:
The return type is incompatible with FragmentPagerAdapter.getItem(int)
Does anyone know what I'm doing wrong here?
My class is extending FragmentPagerAdapter
A Fragment can also have a ListView in it.
FragmentActivity is some support Class, to support Fragments on older devices, i think its pre api 11.
To use a ListView in a Fragment, just create a ListView in the Fragment, or inflate an xml file with a ListView in it.
FragmentPagerAdapter getItem() method needs to return a Fragment. FragmentActivity is not a Fragment, it's an Activity containing Fragments. See here: http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html
Use ListFragment for Fragments having a ListView
http://developer.android.com/reference/android/support/v4/app/ListFragment.html
Your fragment don't need to be FragmentActivity to hold a ListView, actually the Activity should extend FragmentActivity, and your fragment should extend ListFragment, which is:
a fragment that displays a list of items by binding to a data source
such as an array or Cursor, and exposes event handlers when the user
selects an item.
I made a post about it that explains how fragments work, how to implement a ListView inside a fragment and how to integrate Fragments with ViewPager. Here is the link, hope it helps.