Saving Fragment state in ViewPager - android

I tried out the sample code from the API and it didn't really work so I implemented my own:
FragmentPagerSupport
public class FragmentPagerSupport extends FragmentActivity {
static final int NUM_ITEMS = 10;
MyAdapter mAdapter;
ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new MyAdapter(getSupportFragmentManager());
Log.i("Pager", "mAdapter = " + mAdapter.toString());
mPager = (ViewPager)findViewById(R.id.pager);
if (mPager == null)
Log.i("Pager", "mPager = null");
else
Log.i("Pager", "mPager = " + mPager.toString());
Log.i("Pager", "Setting Pager Adapter");
mPager.setAdapter(mAdapter);
}
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
Log.i("Pager", "MyAdapter constructor");
}
#Override
public int getCount() {
Log.i("Pager", "MyAdapter.getCount()");
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
Log.i("Pager", "MyAdapter.getItem()");
return TestFragment.newInstance(position);
}
}
public static class TestFragment extends Fragment {
public static TestFragment newInstance(int position) {
Log.i("Pager", "TestFragment.newInstance()");
TestFragment fragment = new TestFragment();
Bundle args = new Bundle();
args.putInt("position", position);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("Pager", "TestFragment.onCreateView()");
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.fragment_item, null);
int position = getArguments().getInt("position");
TextView tv = (TextView)layout.findViewById(R.id.text);
tv.setText("Fragment # " + position);
tv.setTextColor(Color.WHITE);
tv.setTextSize(30);
return layout;
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
fragment_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/hello"
/>
</LinearLayout>
My question is, instead of creating a new Fragment instance each time the user swipes left and right, how do I save a fragment's state (to some data structure) and then restore it?
The API demo doesn't seem to have any state information saving code at all.

Use ViewPager.setOffscreenPageLimit() in FragmentActivity
ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setOffscreenPageLimit(2);
See more at How do I tell my custom FragmentPagerAdapter to stop destroying my fragments?

just override this method in FragmentpagerAdapter
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
super.destroyItem(ViewGroup container, int position, Object object);
}
remove super.destroyItem(ViewGroup container, int position, Object object);
from your code

Update:
In the getItem of MyAdapter you return a new instance of your Fragment. Android will not call getItem on every swipe. It will only call getItem to get a new instance, but will reuse the existing instances as long as they are availible.
About the state part of the Demo. I can't help you. I think the normal techniques for restoring state in Fragements/Activities apply here, so nothing special when loading it in a ViewPager (but I might be wrong).

If you override
public void destroyItem(View container, int position, Object object)
without calling super, the fragment will not be destroyed and will be reused.

The adapter should be extended from FragmentStatePagerAdapter instead of FragmentPageAdapter and the adapter will keep reference from position to fragment item. On the activity or fragment parent, set listener OnPageChangeListener for PageIndicator to detect the position of fragment item has been activated and update related data's state.
About the data state of fragment item, I think should save/restore state from Activity or Fragement parent.
The adapter can add some code as following:
public static class MyAdapter extends FragmentStatePagerAdapter {
private SparseArray<TestFragment> mPageReferenceMap
= new SparseArray<TestFragment>();
...
#Override
public Object instantiateItem(ViewGroup viewGroup, int position) {
Object obj = super.instantiateItem(viewGroup, position);
//Add the reference when fragment has been create or restore
if (obj instanceof TestFragment) {
TestFragment f= (TestFragment)obj;
mPageReferenceMap.put(position, f);
}
return obj;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
//Remove the reference when destroy it
mPageReferenceMap.remove(position);
super.destroyItem(container, position, object);
}
public TestFragment getFragment(int key) {
return mPageReferenceMap.get(key);
}
...
}
Hope this help.

I tripped on some similar ground...
I wanted to keep my fragments saved within my adapter to avoid useless reloading since I only had 5 fragments in the FragmentPagerAdapter.
I basically had to create an array and override the getItem(position) method:
private StoryListFragment[] fragmentsArray
= new StoryListFragment[getCount()];
public SectionsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if(fragmentsArray[position]!=null)
return fragmentsArray[position];
StoryListFragment storyListFragment = null;
switch(position){
case(0):
storyListFragment = StoryListFragment.newInstance(StoriesBank.NEWS);
break;
case(1):
storyListFragment = StoryListFragment.newInstance(StoriesBank.FEATURES);
break;
case(2):
storyListFragment= StoryListFragment.newInstance(StoriesBank.ARTS);
break;
}
fragmentsArray[position] = storyListFragment;
return storyListFragment;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
StoryListFragment fragment = (StoryListFragment) super.instantiateItem(container, position);
fragmentsArray[position] = fragment;
return fragment;
}

Related

How to update Fragments in ViewPager after updating Adapter?

I call loadCategory method from different items of navigation drawer.
On the first call ViewPager load the correct data. But on the second call data doesn't change. ViewPager shows the old data, Please help.
Thanks in advance.
private void loadCategory(int id) {
toolbar.setTitle(categoryList[id]);
adapter = new PagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
public class PagerAdapter extends FragmentPagerAdapter{
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
#Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
bundle.putString("shayari",currentShayaaris[position]);
Fragment SFragment = new ShayariFragment();
SFragment.setArguments(bundle);
return SFragment;
}
#Override
public int getCount() {
return currentShayaaris.length;
}
}
If you are inside a fragment you should instantiate adapter like this
adapter = new PagerAdapter(getChildFragmentManager());
There are several ways to update
When using FragmentPagerAdapter or FragmentStatePagerAdapter,
if you want to switch out the actual fragments that are being
displayed, you need to avoid FragmentPagerAdapter and use
FragmentStatePagerAdapter.
check this link for more information.Update ViewPager
Override getItemPosition in your PagerAdapter
public int getItemPosition(Object object) {
return POSITION_NONE;
}
second way to update viewpager
You might need to removeView and addView to reload your viewpager to get new changes in your loadCategory function after updating adapter.
ViewGroup parent = (ViewGroup) mViewPager.getParent();
if (parent != null) {
parent.removeView(mViewPager);
mViewPager.getAdapter().notifyDataSetChanged();
parent.addView(mViewPager);
}

notifyDataSetChanged Method Takes Away Smooth Scrolling From Tabs

I am currently using Material Design in an Android app that I am making. In this app, I am using the Material Design tab layout to display some information that I am receiving. However when I tap the tabs, the animation is not smooth, and it is very abrupt. Sliding to go to the other tab, however is very smooth.
mTabLayout = (TabLayout) findViewById(R.id.chem_tab_layout);
mGenericAdapter = new GenericPagerAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.view_pager);
mPager.setAdapter(mGenericAdapter);
//Notice how the Tab Layout links with the Pager Adapter
mTabLayout.setTabsFromPagerAdapter(mGenericAdapter);
//Notice how The Tab Layout and View Pager object are linked
mTabLayout.setupWithViewPager(mPager);
mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout){
#Override
public void onPageSelected(int position) {
mGenericAdapter.notifyDataSetChanged();
}
});
That is my code for setting the adapter, etc.
This is my custom adapter code for the tabs:
class GenericPagerAdapter extends FragmentStatePagerAdapter {
public GenericPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
ChemGridActivity.MyFragment myFragment = new ChemGridActivity.MyFragment();
return myFragment;
}
#Override
public int getCount() {
return 3; //returns number of tabs that need to be created
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0) return "Chemistry";
if (position == 1) return "Mathematics";
if (position == 2) return "Physics";
else return null;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
I feel that the choppy transition between tabs is caused by the overriden method onPageSelected method when I add onPageChangeListener. What do I add to this method to make tapping on tabs a smoother animation?
Without knowing much about the internals of your classes, I imagine the problem is not that you have a listener, but what you are doing inside that listener.
In the case of most adapters notifyDataSetChanged() will cause it to re-render the entire view again (including all pages).
Seeing as you haven't specified what the intent here with the notification is, it's hard to tell you how you can do this in an alternative way, but you do need to do something less intensive if you want the animation to remain smooth.
I suspect you just want to change which fragment is shown, in which case just use the FragmentManager where necessary, remembering to reuse fragments which have already been seen once.
EDIT Based on additional info in comments
#Override
public Fragment getItem(int position) {
//POSITION_SOMETHINHG would be one of a set of constants to indicate hwa to display
return ChemGridActivity.MyFragment.newInstance(ChemGridActivity.MyFragment.POSITION_SOMETHINHG);
}
public class ChemGridActivity.MyFragment ... {
private static final String KEY_DISPLAY_TYPE = "KEY_DISPLAY_TYPE";
public static final int POSITION_SOMETHINHG = 11111;
public static MyFragment newInstance(int display) {
MyFragment f = new MyFragment();
Bundle bund = new Bundle();
bund.putInt(KEY_DISPLAY_TYPE, display);
f.setArguments(bund);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
mDisplay = args.getInt(KEY_DISPLAY_TYPE, 0);
}
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.my_layout, container, false);
//TODO: change something based on mDisplay
return view;
}

Hide Parent Fragment from the Fragment in the viewPager

I have a Fragment A holds a view pager that display serval nested fragments. B and C are the fragments directly hold by the view pager. And each B and C holds a listView. When click listView item fragment D will show up. The problem is that, I could only hide the Fragment C and B from the viewPager, which means Fragment D will come over Fragment A. The question is how could I hide Fragment A from B and C not just hide the Fragment B and C from the viewPager.
here is the code of Fragment A
public class FragmentA extends Fragment {
private View view;
private PagerSlidingTabStrip tabs;
private DisplayMetrics dm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_a, null);
dm = getResources().getDisplayMetrics();
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
tabs = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);
pager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
tabs.setViewPager(pager);
setTabsValue();
initView();
return view;
}
private void initView() {
TextView titleView = (TextView) view.findViewById(R.id.title_content_text);
titleView.setVisibility(View.VISIBLE);
titleView.setText(getString(R.string.label_alert));
}
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
private final String[] titles = { "B", "C" };
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
#Override
public int getCount() {
return titles.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
if (BFrag == null) {
BFrag = new BFrag();
}
return BFrag;
case 1:
if (CFrag == null) {
CFrag = new CFrag();
}
return CFrag;
default:
return null;
}
}
}
}
here is the code in Fragment B that trying to show fragment D:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> list, View v, int pos, long id) {
if (pos < Item.size()) {
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.hide(BFrag.this);
DFrag dFrag = new DFrag();
activity.dFeedFrag = dFrag;
transaction.add(R.id.home_frame_content, dFeedFrag, "dFrag");
transaction.addToBackStack(null);
transaction.commit();
}
}
}
});
The layout file of Fragment A:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include layout="#layout/inculde_title_bar"/>
<com.example.blah.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="40dp" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tabs" />
Anyone could help me, Thanks! =)
Because B, C is hosted in the ViewPager, so they are in the fragment A, so you just need to find fragment A and hide it.
The real question is, where is the id home_frame_content.
If this id is in Fragment A, D will be hidden once A is hidden. I think this is what you want.
So the id home_frame_content must be somewhere not in A. Then you can find A, hide it, you will get what you want.
update 1
And there is a demo: https://github.com/liaohuqiu/ABCDFragment
Hope it would be helpful.

ViewPager Fragments are not initiated in onCreate

I seem to be having an issue updating the fragments that I am using in my ViewPager, regardless of whether I try in onCreate(), onCreateView(), or onResume(). Here is how I'm setting up my ViewPager in my MainFragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_screen, container, false);
mPager = (ViewPager)rootView.findViewById(R.id.pager);
mPager.setOffscreenPageLimit(2); // So all 3 pages are loaded at once.
mAdapter = new JournalPagerAdapter(getActivity().getSupportFragmentManager(), this);
mPager.setAdapter(mAdapter);
// Add bar graph to view
mGraphLayout = (LinearLayout) rootView.findViewById(R.id.journalGraph);
updateGraph();
mGraphLayout.addView(mGraphView);
mPainFrag = (PainFragment)mAdapter.getRegisteredFragment(0);
// Null pointer here, but if I put the action in a button listener, it works.
mPainFrag.setScale(mEntry.getPain());
...
I'm accessing the fragments through some overridden methods in my FragmentPagerAdapter:
public class JournalPagerAdapter extends FragmentPagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
private View.OnClickListener mOnClickListener;
public JournalPagerAdapter(FragmentManager mgr, View.OnClickListener onClickListener) {
super(mgr);
mOnClickListener = onClickListener;
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return PainFragment.newInstance("PainFragment", mOnClickListener);
case 1: return StressFragment.newInstance("StressFragment", mOnClickListener);
case 2: return SleepFragment.newInstance("SleepFragment", mOnClickListener);
default: return PainFragment.newInstance("PainFragment", mOnClickListener);
}
}
#Override
public int getCount() {
return 3;
}
/* Thanks to Streets of Boston (http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager)
*/
#Override
public Object instantiateItem(ViewGroup container, int position) {
Log.v("rx", "itemInstantiated");
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
I can't seem to figure out why the fragment is null right after I set the adapter, but if I put the fragment update code in a click event, I have no issues.
I would try adding a layout listener to your ViewPager to get notified when the laying out of views has occurred.
When you create your ViewPager call mPager.getViewTreeObserver().addOnGlobalLayoutListener() and pass something implementing OnGlobalLayoutListener.
In the callback method, do your fragment updating. Make sure to call mPager.getViewTreeObserver().removeGlobalOnLayoutListener(this) in the callback, otherwise the callback will be called multiple times.
You could instantiate your fragments in the PagerAdapter's constructor and just have getItem return them instead of instantiating them.

Is it possible to access the current Fragment being viewed by a ViewPager?

I have an app with a ViewPager and three Fragments. I'm trying to figure out how to get the current Fragment being viewed so I can get at its arguments.
I have an OnPageChangeListener grabbing the current page index, but
ViewPager.getChildAt(int position);
returns a View. What's the relationship between this View and the current Fragment?
I finally found an answer that worked for me. Basically, you can access the fragment for a viewPager page by using the tag "android:switcher:"+R.id.viewpager+":0".
I've solved this problem the other way round.
Instead of searching for the fragment from the activity, I'm registering the Fragment during it's onAttach() method at it's owner activity and de-registering it in the onStop() method.
Basic Idea:
Fragment:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
mActivity = (IMyActivity)activity;
}catch(ClassCastException e){
throw new ClassCastException(activity.toString() +" must be a IMyActivity");
}
mActivity.addFragment(this);
}
#Override
public void onStop() {
mActivity.removeFragment(this);
super.onStop();
}
IMyActivity:
public interface IFriendActivity {
public void addFragment(Fragment f);
public void removeFragment(Fragment f);
}
MyActivity:
public class MyActivity implements IMyActivity{
[...]
#Override
public void addFragment(Fragment f) {
mFragments.add(f);
}
#Override
public void removeFragment(Fragment f) {
mFragments.remove(f);
}
}
Edit - Don't do this. If you're tempted to, read the comments for why it's a bad idea.
On the odd-chance you're still trying to solve this problem:
Extend FragmentPagerAdapter. In the constructor, build the Fragments you need and store them in a List (array/ArrayList) of Fragments.
private final int numItems = 3;
Fragment[] frags;
public SwipeAdapter (FragmentManager fm) {
super(fm);
//Instantiate the Fragments
frags = new Fragment[numItems];
Bundle args = new Bundle();
args.putString("arg1", "foo");
frags[0] = new MyFragment();
frags[1] = new YourFragment();
frags[2] = new OurFragment();
frags[2].setArguments(args);
}
Then for getItem(int position), you can do something like
public Fragment getItem(int position) {
return frags[position];
}
I'm not sure if this is the generally accepted way of doing it but it worked for me.
Edit
This is really not a good way to go. If you plan on handling orientation changes or your app going into the background, then this will probably break your code. Please read the comments below this answer for more info. Rather use #James 's answer
Yes, it's possible if you are using FragmentStatePagerAdapter.
ViewPager vp;
//...
YourFragment fragment = (YourFragment) adapter.instantiateItem(vp, vp.getCurrentItem());
PLEASE DON'T USE THIS
Make your adapter extend the following FragmentStatePagerWithCurrentAdapter class and instead of implementing getItem implement the same code into getItemAtIndex
Set the ViewPager OnPageChangeListener, to the instance of the adapter.
When you need to access the current Fragment you just call adapter.getCurrentItem().
package your.package;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.SparseArray;
import android.view.ViewGroup;
public abstract class FragmentStatePagerWithCurrentAdapter
extends FragmentStatePagerAdapter
implements OnPageChangeListener {
int currentPage = 0;
private SparseArray<Fragment> mPageReferenceMap = new SparseArray<Fragment>();
public FragmentStatePagerWithCurrentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public final Fragment getItem(int index) {
Fragment myFragment = getItemAtIndex(index);
mPageReferenceMap.put(index, myFragment);
return myFragment;
}
public abstract Fragment getItemAtIndex(int index);
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
mPageReferenceMap.remove(Integer.valueOf(position));
}
public Fragment getCurrentItem() {
return mPageReferenceMap.get(currentPage);
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int newPageIndex) {
currentPage = newPageIndex;
}
}
I used as reference the following blog post: http://tamsler.blogspot.com/2011/11/android-viewpager-and-fragments-part-ii.html
It's been explained here : http://developer.android.com/guide/topics/fundamentals/fragments.html
In OnCreateView you must return a view to draw a UI for your fragment, I think that's the relationship.
Also this question might be similar: Get focused View from ViewPager
You can do so:
- On the class extent of a view pager adapter (such as PagerAdapter , FragmentStatePagerAdapter...) override method instantiateItem :
#Override
public Object instantiateItem(ViewGroup container, int position) {
final Fragment frag = (Fragment) super.instantiateItem(container, position);
if(frag instanceof ListNoteOfTypeFragment){
final ListNoteOfTypeFragment listNoteOfTypeFragment = (ListNoteOfTypeFragment) frag;
//do whatever you want with your fragment here
listNoteOfTypeFragment.setNoteChangeListener(mListener);
}
return frag;
}
Definitive answer that works seamlessly (but small hack):
somewhere in page fragment's layout:
<FrameLayout android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone" android:id="#+id/fragment_reference">
<View android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
</FrameLayout>
in fragment's onCreateView():
...
View root = inflater.inflate(R.layout.fragment_page, container, false);
ViewGroup ref = (ViewGroup)root.findViewById(R.id.fragment_reference);
ref.setTag(this);
ref.getChildAt(0).setTag("fragment:" + pageIndex);
return root;
and method to return Fragment from ViewPager, if exists:
public Fragment getFragment(int pageIndex) {
View w = mViewPager.findViewWithTag("fragment:" + pageIndex);
if (w == null) return null;
View r = (View) w.getParent();
return (Fragment) r.getTag();
}
Jorge Garcia's FragmentStatePagerWithCurrentAdapter is a very good solution but it needs a minor improvement. In case the activity gets destroyed and re-created in response to a configuration change or something like that the getItem will not be called for the fragments that were saved and retrieved by the fragment manager. So I override getItem normally in my subclass and I put the following in the FragmentStatePagerWithCurrentAdapter
#Override
public Object instantiateItem(ViewGroup container, int position) {
Object item = super.instantiateItem(container, position);
if ( item instanceof Fragment ) {
pageReferenceMap.put(position, (Fragment)item);
}
return item;
}
The instantiateItem is called every time the fragment in that position is accessed.
Or just save all Fragments in a map:
public class MyFragment extends Fragment implements OnPageChangeListener {
private ViewPager viewPager;
private FragmentStatePagerAdapter viewAdapter;
private View rootView;
private Map<Integer, Fragment> fragments = new HashMap<Integer, Fragment>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.introdution, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.pager);
viewAdapter = new ViewAdapter(getFragmentManager());
viewPager.setAdapter(viewAdapter);
viewPager.addOnPageChangeListener(this);
return rootView;
}
private class ViewAdapter extends FragmentStatePagerAdapter {
public ViewAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
Fragment result = null;
switch (position) {
case 0: result = Fragment1.newInstance(); break;
case 1: result = Fragment2.newInstance(); break;
}
if (result != null)
fragments.put(position, result);
return result;
}
#Override
public int getCount() {
return 2;
}
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int position) {
Fragment currentFragment = fragments.get(position);
}
}
I think there is the better way by using this
Log.i(TAG, "getCurrentItem " + mViewPager.getCurrentItem());
Can get the current display fragment page.

Categories

Resources