AndroidでViewpager
を使用すると、ページを最後までプログラムで移動できますか?たとえば、5ページあり、ページ#2を最後のポジション(5位)に移動して、ページ3が2に、4が3に、5が4になるようにしたいですか?Android ViewPager:任意のページをプログラム的に終了するには移動しますか?
ありがとうございました
AndroidでViewpager
を使用すると、ページを最後までプログラムで移動できますか?たとえば、5ページあり、ページ#2を最後のポジション(5位)に移動して、ページ3が2に、4が3に、5が4になるようにしたいですか?Android ViewPager:任意のページをプログラム的に終了するには移動しますか?
ありがとうございました
はい。私はどのように行ったのかを示すことであなたのケースに挑戦してみるつもりです。あなたのケースの例を私のコードサンプルの下に示します。
基本的に、これを達成するには、フラグメントの位置を把握しておく必要があります。以下は、私が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()
を呼び出します。そのメソッド呼び出しの結果は、ページ(この場合はフラグメント)が表示されるかどうかを決定します。
私はこのすべてを読んでいます。
ViewPagerを使用する通常の方法は、適切なページを適切なタイミングでフィードするPagerAdapterクラスを用意することです。 PagerAdapter、FragmentPagerAdapter、FragmentStatePagerAdapterの使いやすいサブクラスがあります。
しかし、ページ順序を変更できるようにするには、PagerAdapterの独自のサブクラスを作成する必要があります。基本的にViewPagerには、ページ番号とアダプタが与えたキーオブジェクトの2つの方法があります。したがって、あなたはViewPagerがあまりにも失われることなく、注文を変更することができなければなりません。
どのように行われたのかの詳細はthis pageです。私はまだしようとしていないが、来るべき数週間は来るだろう。私はページがすべてを言っているとは思わない。ほとんどのアダプタクラスには必要なgetItem()メソッドはありません。だから私は実際にページがViewPagerにどのように追加されるのかまだ見ていない。
いくつかのサンプルコードを見つけて読む時間です。
非常に分かりやすい。この実装でFragmentStatePagerAdapterを使用していない理由は何ですか?あなたのmItemsのリストは、大規模なクラスが使いやすさの理由をすべて失うことになりますか? – jbenowitz
これも私の助けにはならなかった。私はアイテムをすべて削除しています。私が次のアイテムに行ったときは、前のアイテムを削除したときにスワイプしますが、中途半端にスワイプすると、次のアイテムはそれ以降のアイテムに変更されます。視覚的に: アダプター内のA、B、Cのアイテム Aを表示し、Bにスワイプします。Aを、Bにスワイプして、Cにフラッシュします。 – jbenowitz
はい、これは予想されます。 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