1. ホーム
  2. android

[解決済み] ViewPager PagerAdapter がビューを更新しない

2022-03-15 04:10:54

質問

互換性ライブラリのViewPagerを使用しています。いくつかのビューを表示させることに成功し、ページをめくることができるようになりました。

しかし、新しいViewsのセットでViewPagerを更新する方法がわからず、困っています。

を呼び出すなど、いろいろと試してみました。 mAdapter.notifyDataSetChanged() , mViewPager.invalidate() 新しいデータのリストを使用するたびに、新しいアダプタを作成する必要があります。

何も役に立ちませんでした。textviewsは元のデータから変更されないままです。

更新しました。 ちょっとテストプロジェクトを作ったら、ほぼビューの更新ができるようになった。下にクラスを貼り付けておきます。

しかし、更新されないのは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) {
        }
    }
}

解決方法は?

そのためには、いくつかの方法があります。

最初の選択肢は簡単ですが、少し非効率です。

オーバーライド getItemPosition を使用します。 PagerAdapter をこのようにします。

public int getItemPosition(Object object) {
    return POSITION_NONE;
}

このようにすると notifyDataSetChanged() の場合、ビューページャーはすべてのビューを削除し、それらをすべて再読み込みします。このように、リロードの効果が得られます。

2つ目のオプション。 Alvaro Luis Bustamante (以前はalvarolb)によって提案されました。 にすることです。 setTag() メソッドを instantiateItem() を、新しいビューをインスタンス化する際に使用します。その際 notifyDataSetChanged() を使用することができます。 findViewWithTag() をクリックして、更新したいビューを探します。

2番目の方法は、非常に柔軟で高いパフォーマンスを発揮します。オリジナルの研究をしたalvarolbに賛辞を送ります。