9

ViewpagerAndroid でを使用して、プログラムで任意のページを最後に移動することは可能ですか? たとえば、5 つのページがあり、ページ #2​​ を最後の位置 (5 番目の位置) に移動して、ページ 3 を 2 に、4 を 3 に、5 を 4 にするとします。

ありがとう

4

2 に答える 2

34

はい。私がどのようにそれを行ったかを示すことで、あなたのケースに答えようとします.コードサンプルの下にあなたのケースの例を示します.

基本的に、これを達成するには、フラグメントがどの位置にあるかを追跡する必要があります。FragmentPagerAdapter以下は、データ ソースとして ArrayList を使用するmy に使用した実装です。

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呼び出すと、ViewPager からアイテムが削除されます (現在表示されている場合でも)。notifyDataSetChanged()MyFragmentPagerAdapter

たとえばthis.dataset、5 つの項目が含まれていて、#2 を ViewPager の最後に移動するとします。これを実現するには、item#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(..)ます。そのメソッド呼び出しの結果によって、ページ (この場合は Fragment) が表示されるかどうか、および表示される場所が決まります。

于 2013-02-11T22:24:57.520 に答える
1

私はこれをすべて読んでいます。

ViewPagerを使用する通常の方法は、適切なタイミングで適切なページにフィードするPagerAdapterクラスを用意することです。PagerAdapter、FragmentPagerAdapter、FragmentStatePagerAdapterには、使いやすいサブクラスがあります。

ただし、ページの順序を変更できるようにするには、PagerAdapterの独自のサブクラスを作成する必要があります。基本的に、ViewPagerが現在のページを認識する方法は2つあります。ページ番号と、アダプターが指定したキーオブジェクトです。したがって、ViewPagerが失われることなく順序を変更できるはずです。

それがどのように行われるかについての厄介な詳細は、このページにあります。私はまだ試していませんが、これから数週間のうちにやっていきます。そのページはすべてを言っているわけではないと思います。ほとんどのAdapterクラスに必要なgetItem()メソッドについては言及されていません。そのため、ページがViewPagerにどのように追加されるかはまだわかりません。

サンプルコードを見つけて読む時間です。

于 2013-01-02T01:39:00.987 に答える