updating viewpager with fragments in a new order

狂风中的少年 提交于 2019-12-07 02:57:41

问题


I have a ViewPager set up that is drawing the data for its pages (views) from data passed down from a server. On occasion, the server will send down new data that will re-order the views (and sometimes add new views) and I need to make that happen seamlessly on my android device while the user is currently viewing a particular fragment.

I have it set to call notifyDataSetChanged() when the new data is pulled down from the server, but that seems to keep a cached version of the slides to the left and right of the currently viewed slide which potentially will change with the reorder. I have looked at this topic here: ViewPager PagerAdapter not updating the View and implemented the first solution which works fine, other than it reloads the current slide that is being viewed which won't work for my purposes. I took a shallow-dive look into implementing the setTag() method proposed on that same page in the second answer and that would work for updating information on the slides, but it won't help me for reordering them.

is there some way I can reorder all of the slides behind the scenes w/o causing any burps in the currently viewed slide?

TIA

EDIT: adding code and asking for some further clarification

This is my Adapter class.

    private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
    ContestEntriesModel entries;

    public ScreenSlidePagerAdapter(FragmentManager fm, ContestEntriesModel Entries) {
        super(fm);
        this.entries = Entries;
    }

    @Override
    public long getItemId(int position) {
        return entries.entries[position].ContestEntryId;

    }

    @Override
    public int getItemPosition(Object object) {
        android.support.v4.app.Fragment f = (android.support.v4.app.Fragment)object;
        for(int i = 0; i < getCount(); i++){

            android.support.v4.app.Fragment fragment = getItem(i);
            if(f.equals(fragment)){
                return i;
            }
        }
        return POSITION_NONE;
    }


    @Override
    public android.support.v4.app.Fragment getItem(int position) {

        long entryId = getItemId(position);
        //Log.d("EntryIds",Integer.toString(entryId));
        if(mItems.get(entryId) != null) {
            return mItems.get(entryId);
        }
        Fragment f = ScreenSlidePageFragment.create(position);
        mItems.put(entryId, f);
        return f;
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }
}

And here is what I'm using when a new payload comes down from the server:

    @Override
    protected void onPostExecute(ContestEntriesModel entries) {
        Fragment currentFragment = ContestEntries.mItems.get(ContestEntries.CurrentEntryId);
        Log.d("fromUpdate",Long.toString(ContestEntries.CurrentEntryId));
        ContestEntries.Entries = entries;
        ContestEntries.NUM_PAGES = ContestEntries.Entries.entries.length;
        ContestEntries.mPagerAdapter.notifyDataSetChanged();
        ContestEntries.mPager.setCurrentItem(ContestEntries.mPagerAdapter.getItemPosition(currentFragment));
    }

回答1:


Check my answer here. The key is to override both getItemId(int) and getItemPosition(Object) in your adapter.

getItemId(int) is used to identify your pages uniquely within your dataset. getItemPosition(Object) is used to fetch the (updated) position for this unique page in your dataset.

If you want to keep focus on the same page before and after updating (adding/removing pages), you should call viewpager.setCurrentItem(int) for the new position of your page after calling .notifyDataSetChanged() on your adapter.



来源:https://stackoverflow.com/questions/17152956/updating-viewpager-with-fragments-in-a-new-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!