14

Hopefully someone can help me with a slight problem/confusion I have with Viewpagers and saving data.

PROBLEM:

When scrolling across the four views I have, the first view has two spinners, two textviews that display a string or a selected item. if I scroll on to the third page and back to the second page, the data in the first view is lost. hense needing to save the data.

Would this be done in the two routines stated below? (best guess is it would be) if so, what sort of commands need to be stated?

CODE:

@Override   
public void restoreState(Parcelable arg0, ClassLoader arg1) {       
}

@Override
public Parcelable saveState() {
    return null;
}

EXTRA INFO: the viewpager is being used in

public Object instantiateItem(View collection, int position) {
}

The complete list of methods are as follows:

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
    ((ViewPager) arg0).removeView((View) arg2);
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
    return arg0 == ((View) arg1);
}

@Override
public Parcelable saveState() {
    return null;
}

@Override
public void finishUpdate(View arg0) {
}

@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}

@Override
public void startUpdate(View arg0) {
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Hadden11
  • 145
  • 1
  • 1
  • 4

1 Answers1

48

Instead of saving the state of those pages you could modify your ViewPager so it buffers all of your pages instead of destroying them and recreating them when you scroll.

So for example if you have 4 pages:

ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setOffscreenPageLimit(3); // the number of "off screen" pages to keep loaded each side of the current page
pager.setAdapter(new PageAdapter(context));

Now your pages will be kept 'alive'

Be careful with this technique however because it will increase memory consumption. The number passed to setOffscreenPageLimit() is the number of pages each side of the current page to retain. In this case we have 4 pages in total so the worst case scenario is when we are at the far edge of of the page set - we have the currently visible page and then the remaining 3 pages are off screen to one side and are thus kept in memory. However, with a larger data set it could potentially mean 7 pages are kept in memory (current page plus 3 either side).

Generally the more optimal solution would be to properly deal with unloading and reloading the page state and re-render them.

Hope this helps

Dean Wild
  • 5,886
  • 3
  • 38
  • 45
  • i didnt know there was a off screen limit, will have a look at that and let you know. Thanks for your advice :) – Hadden11 Jan 17 '12 at 10:19
  • dont know if its something I am doing wrong but when entering that off screen limit it comes up with --> The method setOffscreenPageLimit(int) is undefined for the type doesnt seem to like being linked with a viewpager – Hadden11 Jan 17 '12 at 10:53
  • what does the import look like for your viewpager? should be import android.support.v4.view.ViewPager; – Dean Wild Jan 17 '12 at 11:00
  • the viewpager import is android.support.v4.view.ViewPager, I've re-imported it just incase its needed it with the edition to the off screen page limit. the quick fix eclipse brings up is to add cast to viewpager and makes it an object if you click on it – Hadden11 Jan 17 '12 at 11:05
  • The docs for viewpager: http://developer.android.com/reference/android/support/v4/view/ViewPager.html and the method is listed there? – Dean Wild Jan 17 '12 at 11:17
  • I have been looking at the link just as i posted the question. If i type in "pager." then press Ctrl+SpaceBar for the template proposals, setOffscreenPageLimit does not appear. would it be a case that i've not imported ViewPager correctly? – Hadden11 Jan 17 '12 at 11:33
  • your import looks good. Would need to see your code to troubleshoot further – Dean Wild Jan 17 '12 at 11:39
  • //routine for inflating pages public Object instantiateItem(View collection, int position) { LayoutInflater inflater = (LayoutInflater)collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); int resId = 0; switch (position) { case 0: resId = R.layout.detailspage; break; case 1: resId = R.layout.resultpage; break; } View view = inflater.inflate(resId, null); ((ViewPager) collection).addView(view, 0); – Hadden11 Jan 17 '12 at 13:51
  • UserPageAdapter adapter = new UserPageAdapter(); ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setOffScreenPageLimit(4); //viewPager.setoff viewPager.setAdapter(adapter); //viewPager.setAdapter(new PageAdapter(context)); viewPager.setCurrentItem(1); – Hadden11 Jan 17 '12 at 13:52
  • All seems to be in order, very strange. The only other thing I can suggest is it you zip up the project and send it to me or post it on GitHub. – Dean Wild Jan 17 '12 at 14:14
  • found the problem, after a few hours found that i installed the newest updates with ice cream sandwich bits then add compatibility librarys and its fine now. Before i was only adding the compatibility librarys which seems to give you only half the functionality of viewpager yet it still works (to a certain point). Thanks so much for your help, shame i cant buy you a pint – Hadden11 Jan 18 '12 at 09:41
  • Very odd. Glad you got it sorted! – Dean Wild Jan 18 '12 at 09:46
  • Dean. Your answer works for my problem too but out of interest were you to not want to save 3/4 page states would these functions be the correct way to go about resolving the issue? – Thomas Clowes Apr 22 '13 at 14:04
  • Why is it that this is the accepted answer? Doesn't it make more sense to use the save state methods instead of consuming extra amounts of memory. – stevebot Mar 18 '14 at 23:29
  • @stevebot - agreed that this is less than optimal from a memory standpoint. For me (and often in other peoples cases) I really did want my views to be retained because they were very heavy and I liked the responsiveness it offered. I was willing to sacrifice the memory for the performance. – Dean Wild Mar 31 '14 at 13:59