I
I
Ivan Chumak2012-10-21 10:21:15
Android
Ivan Chumak, 2012-10-21 10:21:15

How to make an infinite ViewPager with three items in Android?

The task is to implement “endless” page scrolling using ViewPager and PagerAdapter. The elements are View (not Fragment). All views are created from a single xml-layout via inflater, they differ only in content. The content is loaded from the API.
In the ViewPager parameters, I set a limit on the limit of inactive pages on the left and right:
mViewPager.setOffscreenPageLimit(1);
Thus, 1 active page can be stored at the same time and 1 on the left and on the right, if there are more of them, the corresponding page is called. deletion method in PagerAdapter-e. At startup, there is 1 id for which content is loaded from the Internet with API (image + text). After loading the first page, the api sends a response with the id of the next page, if any. I store page id-shniks in ArrayList: when creating an adapter, I initialize this list with the first value (id of the initial page), when I get the next id, I add the following value there. It turns out that at startup I have an adapter whose getCount returns the size of this id array (mPagesId), at the beginning it is 1. Next, the adapter requests the 0th position for the ViewPager:

@Override
    public Object instantiateItem(ViewGroup collection, int position) {
       int pageId = Integer.valueOf(mPagesId.get(position));
       View newView = createNewView();
       newView.setId(pageId);
       ((ViewPager) collection).addView(newView);
       // start post loading if there is active network connection
       if (ConnectionUtils.isOnline(mContext)) {
           TaskLoadPost loadPostTask = new TaskLoadPost();
           loadPostTask.execute(pageId);
       } else {
           DialogUtil.showNetworkErrorDialog((Activity) mContext);
       }
       return newView;
    }

In the background, I fill the views with data from the Web and in the same place I get a new id, which I add to the array:
mPagesId.add(id);
After that, the adapter calls the instantiateItem (...) method again, then the id is taken from the array by position and everything repeats further: we added a new view, loaded it , loaded trace. Id, placed in an array, etc.
In the first steps, everything is fine (I'm only considering scrolling to the right now), except that when it reaches 3 or 4 elements, the adapter calls the destroyItem() method before initializing the new page:
((ViewPager) collection).removeView((View) view);

    View page = (View) view;
    mPagesId.remove(String.valueOf(page.getId()));
    notifyDataSetChanged();

OK, deleted, everything seems to be in order. After that, the size of the array becomes equal to 3m. Here the most interesting thing begins: after removing the 0 element, we are no longer called in the initiate method as it would be logical to assume with the 2 element - position == 2 (after all, we only have 3 pages stored), but from 3 - we climb on this position for Id , but we don’t find id there, because the array has just been "compressed". Well, okay, I think, somehow you can get out. We skipped, scrolled, deleted again, again we get into initiate ... again, it is logical to expect position == 2, 3, or hell with it, 4 ... but position comes equal to 1! What kind of unit is this and where and why it comes from is a big mystery to me. Again, this can be bypassed with shit code, and in the case of scrolling to the right, it is further called only with position = 1 - why and how it is not clear to me.
In general, the essence of the question is: how can one normally synchronize and “make friends” with some kind of structure that stores auxiliary data for pages in the ViewPager, with the behavior that occurs in ViewPager and the add / remove methods it calls with incomprehensible positions. I really need an additional array synchronized with the internal storage of the View in the ViewPager, otherwise it is not possible to load the next / previous pages with the API with the correct id-s, while deleting unnecessary pages and id. Has anyone experienced something similar? Maybe there are some more elegant tasks to solve my problem? Maybe I somehow misunderstand the whole trick of when and how the ViewPager calls the methods of its adapter? For me these positions are really unclear,
I would be very grateful for any advice, I've been struggling with this for about a week now ...

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Radegast, 2012-10-21
@Radegast

Why are you removing it from your list? Pager only does this for efficiency reasons, as far as I know. Why not leave your list alone? If, for example, the user began to scroll back, will the download of what was already there or something else start again?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question