Android ViewPager:移动任何页面以编程方式结束?

时间:2012-09-07 15:59:17

标签: android-viewpager

在Android中使用Viewpager,是否可以通过编程方式将任何页面移至最后?例如,我有五页并希望将页面#2移动到最后一个位置(第五个位置),因此第3页变为2,4,变为3,5变为4?

感谢

2 个答案:

答案 0 :(得分:33)

是。我将通过展示我是如何做到这一点来尝试回答你的案例,我将在我的代码示例下面展示你的案例。

基本上,要实现这一点,您必须跟踪碎片的位置。下面是我用于FragmentPagerAdapter的实现,它使用ArrayList作为其数据源。

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    private HashMap<Long, Fragment> mItems
                    = new HashMap<Long, Fragment>();

    private ArrayList<MyObject> dataset;

    public MyFragmentPagerAdapter(ArrayList<MyObject> objects) {
        this.dataset = objects;
    }

    @Override
    public int getCount() {
        return dataset.size();
    }

    @Override
    public Fragment getItem(int position) {
        long id = getItemId(position);

        if(mItems.get(id) != null) {
            // caching to prevent multiple instances of the same fragment
            // for the same position/id
            return mItems.get(id);
        }

        Fragment f = Fragment.newInstance();

        mItems.put(id, f);

        return f;
    }

    @Override
    public long getItemId(int position) {
        // return a unique id
        return dataset.get(position).getUniqueId();
    }

    @Override
    public int getItemPosition(Object object) {
        /*
         * Purpose of this method is to check whether an item in the adapter
         * still exists in the dataset and where it should show.
         * For each entry in dataset, request its Fragment.
         * 
         * If the Fragment is found, return its (new) position. There's
         * no need to return POSITION_UNCHANGED; ViewPager handles it.
         * 
         * If the Fragment passed to this method is not found, remove all
         * references and let the ViewPager remove it from display by
         * by returning POSITION_NONE;
         */
        Fragment f = (Fragment) object;

        for(int i = 0; i < getCount(); i++) {

            Fragment item = (Fragment) getItem(i);
            if(item.equals(f)) {
                // item still exists in dataset; return position
                return i;
            }
        }

        // if we arrive here, the data-item for which the Fragment was created
        // does not exist anymore.

        // Also, cleanup: remove reference to Fragment from mItems
        for(Map.Entry<Long, MainListFragment> entry : mItems.entrySet()) {
            if(entry.getValue().equals(f)) {
                mItems.remove(entry.getKey());
                break;
            }
        }

        // Let ViewPager remove the Fragment by returning POSITION_NONE.
        return POSITION_NONE;
    }
}

现在,如果您从数据集(this.dataset)中删除某个项目并在notifyDataSetChanged()的实例上调用MyFragmentPagerAdapter,则会从ViewPager中删除该项目(即使它当前正在看)。

假设this.dataset包含5个项目,您希望将#2移动到ViewPager的末尾。要实现这一点,您必须将项目#2定位到数据源的末尾(通过Collection.Sort或其他方式)。我会告诉你简单的方法。

ArrayList<MyObject> list = new ArrayList<>();
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(list);
viewpager.setAdapter(adapter);

...

MyObject item = list.get(2);
list.remove(item);
list.add(item); // now it's positioned at the end of the list
adapter.notifyDataSetChanged(); // voilá, that should do the trick!

adapter.notifyDataSetChanged()最终会调用viewpager.dataSetChanged(),而adapter.getItemPosition(..)会在其每个页面上调用{{1}}。该方法调用的结果确定页面(在这种情况下为片段)将显示的位置和位置。

答案 1 :(得分:1)

我刚读过这一切。

使用ViewPager的常用方法是使用PagerAdapter类,在适当的时候将其提供给正确的页面。 PagerAdapter,FragmentPagerAdapter和FragmentStatePagerAdapter有很好的子类,它们更容易使用。

但是,为了能够更改页面顺序,您必须编写自己的PagerAdapter子类。基本上,ViewPager有两种方式可以识别您所在的页面:页码,以及适配器为其提供的密钥对象。因此,您应该能够在没有ViewPager太丢失的情况下更改订单。

关于如何完成的详细信息在this page上。我还没有尝试,但我会在未来几周内。我认为那个页面并没有说出一切。它没有提到大多数Adapter类必须具有的getItem()方法。所以我真的还没看到如何将这些页面添加到ViewPager中。

找到并阅读一些示例代码的时间。