Android ViewPager: переместить любую страницу для завершения программно?

Используя Viewpager в Android, можно ли программно переместить любую страницу в конец? Например, у меня есть пять страниц и вы хотите переместить страницу №2 в последнюю позицию (5-я позиция), так что страница 3 становится 2, 4 становится 3, а 5 становится 4?

спасибо

Ответ 1

Да. Я попытаюсь ответить на ваш случай, показывая, как я это сделал, и я покажу пример для вашего примера ниже моего образца кода.

В принципе, для этого вам нужно отслеживать, какие позиции имеют ваши фрагменты. Ниже приведена реализация, которую я использовал для моего 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 positioned at the end of the list
adapter.notifyDataSetChanged(); // voilá, that should do the trick!

adapter.notifyDataSetChanged() в конечном итоге вызывает viewpager.dataSetChanged(), который, в свою очередь, вызывает adapter.getItemPosition(..) на каждой из своих страниц. Результат этого вызова метода определяет, будет ли отображаться страница (фрагмент в этом случае).

Ответ 2

Я только что читал все это.

Обычный способ использования ViewPager состоит в том, что он имеет класс PagerAdapter, который передает ему правильные страницы в нужный момент. Есть хорошие подклассы PagerAdapter, FragmentPagerAdapter и FragmentStatePagerAdapter, которые легче использовать.

Однако, чтобы иметь возможность изменять порядок страниц, вам придется писать собственный подкласс PagerAdapter. В основном существует два способа, с помощью которых ViewPager знает, на какой странице вы находитесь: номер страницы и ключевой объект, предоставленный адаптером. Следовательно, вы должны иметь возможность изменять порядок без потери ViewPager.

Подробные сведения о том, как это делается, находятся на на этой странице. Я еще не пытался, но я буду в ближайшие недели. Я думаю, что страница не говорит все. Он не упоминает метод getItem(), который должен иметь большинство классов адаптера. Поэтому я действительно не вижу, как страницы добавляются в ViewPager.

Время, чтобы найти и прочитать пример кода.