互換性ライブラリの ViewPager を使用しています。ページングできる複数のビューを表示することに成功しました。
しかし、ViewPager を新しいビューのセットで更新する方法がわかりません。
新しいデータ リストを使用するたびに、を呼び出したりmAdapter.notifyDataSetChanged()
、まったく新しいアダプターを作成したりするなど、さまざまなことを試しました。mViewPager.invalidate()
何も役に立たず、テキストビューは元のデータから変更されていません。
更新:小さなテスト プロジェクトを作成し、ビューをほぼ更新できるようになりました。以下にクラスを貼り付けます。
ただし、2 番目のビューでは更新されないようで、「B」が残ります。更新ボタンを押すと、「Y」が表示されるはずです。
public class ViewPagerBugActivity extends Activity {
private ViewPager myViewPager;
private List<String> data;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
data = new ArrayList<String>();
data.add("A");
data.add("B");
data.add("C");
myViewPager = (ViewPager) findViewById(R.id.my_view_pager);
myViewPager.setAdapter(new MyViewPagerAdapter(this, data));
Button updateButton = (Button) findViewById(R.id.update_button);
updateButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
updateViewPager();
}
});
}
private void updateViewPager() {
data.clear();
data.add("X");
data.add("Y");
data.add("Z");
myViewPager.getAdapter().notifyDataSetChanged();
}
private class MyViewPagerAdapter extends PagerAdapter {
private List<String> data;
private Context ctx;
public MyViewPagerAdapter(Context ctx, List<String> data) {
this.ctx = ctx;
this.data = data;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object instantiateItem(View collection, int position) {
TextView view = new TextView(ctx);
view.setText(data.get(position));
((ViewPager)collection).addView(view);
return view;
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public void startUpdate(View arg0) {
}
@Override
public void finishUpdate(View arg0) {
}
}
}
ベストアンサー1
これを実現するにはいくつかの方法があります。
最初のオプションは簡単ですが、少し非効率的です。
getItemPosition
次のように上書きしますPagerAdapter
:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
この方法では、 を呼び出すとnotifyDataSetChanged()
、ビュー ページャーはすべてのビューを削除し、それらをすべて再ロードします。このようにして、再ロード効果が得られます。
2番目の選択肢は、Alvaro Luis Bustamante (旧alvarolb) が提案は、新しいビューをインスタンス化するときにsetTag()
の メソッドを使用しますinstantiateItem()
。その後、 を使用する代わりにnotifyDataSetChanged()
、 を使用してfindViewWithTag()
更新するビューを見つけることができます。
結論
ビューが多数ある場合、または特定のアイテムやビューの変更を(いつでも迅速に)サポートしたい場合は、変更されていないビューをすべて再作成する必要がないため、2 番目のアプローチ(タグ付け)が非常に柔軟でパフォーマンスに優れています。
(元の調査を行った alvarolb に感謝します。)
ただし、アプリに「更新」機能のみがある場合 (単一アイテムの変更も許可されていない場合)、またはアイテムが少数しかない場合は、開発時間を節約できる最初のアプローチを使用します。