2012-09-07 13 views

答えて

31

はい。私はどのように行ったのかを示すことであなたのケースに挑戦してみるつもりです。あなたのケースの例を私のコードサンプルの下に示します。

基本的に、これを達成するには、フラグメントの位置を把握しておく必要があります。以下は、私がFragmentPagerAdapterのために使用した実装で、ArrayListをデータソースとして使用しています。あなたがデータセット(this.dataset)から項目を削除し、MyFragmentPagerAdapterのインスタンスにnotifyDataSetChanged()を呼び出す場合

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; 
    } 
} 

さて、それは(それが現在表示されていた場合でも)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()は最終的に順番にそのページのそれぞれにadapter.getItemPosition(..)を呼び出すviewpager.dataSetChanged()を呼び出します。そのメソッド呼び出しの結果は、ページ(この場合はフラグメント)が表示されるかどうかを決定します。

+1

非常に分かりやすい。この実装でFragmentStatePagerAdapterを使用していない理由は何ですか?あなたのmItemsのリストは、大規模なクラスが使いやすさの理由をすべて失うことになりますか? – jbenowitz

+0

これも私の助けにはならなかった。私はアイテムをすべて削除しています。私が次のアイテムに行ったときは、前のアイテムを削除したときにスワイプしますが、中途半端にスワイプすると、次のアイテムはそれ以降のアイテムに変更されます。視覚的に: アダプター内のA、B、Cのアイテム Aを表示し、Bにスワイプします。Aを、Bにスワイプして、Cにフラッシュします。 – jbenowitz

+0

はい、これは予想されます。 Aを削除すると、Bはpos == 0、C pos == 1になります。現在のアイテム( 'viewPager.setCurrentItem(int)')は、AからBにスワイプすると1に設定されます.Aを削除すると、現在の位置は1のままです。つまり、 'ViewPager'がCにジャンプします。これを修正するには、Aを削除するときに 'viewPager.setCurrentItem(adapter.getItemPosition(fragment-B))'を設定します。 – Reinier

1

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

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

しかし、ページ順序を変更できるようにするには、PagerAdapterの独自のサブクラスを作成する必要があります。基本的にViewPagerには、ページ番号とアダプタが与えたキーオブジェクトの2つの方法があります。したがって、あなたはViewPagerがあまりにも失われることなく、注文を変更することができなければなりません。

どのように行われたのかの詳細はthis pageです。私はまだしようとしていないが、来るべき数週間は来るだろう。私はページがすべてを言っているとは思わない。ほとんどのアダプタクラスには必要なgetItem()メソッドはありません。だから私は実際にページがViewPagerにどのように追加されるのかまだ見ていない。

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

関連する問題