1. ホーム
  2. android

[解決済み] ViewPagerがコンテンツを再描画せず、空白のままになる。

2023-04-11 18:27:52

質問

ViewPagerで非常に奇妙な問題に悩まされています。各 ViewPager ページにリストを埋め込み、リスト データを更新するときにリスト アダプタと View Pager アダプタの両方で notifyDataSetChanged をトリガします。

観察されるのは、時々、ページがそのビュー ツリーを更新しない、つまり空白のままであったり、時にはページングすると消えてしまったりすることです。数回ページングを行ったり来たりすると、コンテンツが突然再表示されます。これは、Android がビューの更新を逃しているように思えます。また、階層ビューアを使用してデバッグする場合、ビューを選択すると必ず再表示されることに気づきました。これは、階層ビューアが選択したビュー自体を強制的に再描画するためと思われます。

リストビュー、またはビューページャー全体を無効にしても効果がありませんでした。

これは compatibility-v4_r7 ライブラリを使用したものです。ビュー ページャーに関連する多くの問題を修正すると主張しているので、最新のリビジョンも使用しようとしましたが、問題はさらに悪化しました (たとえば、ジェスチャが壊れて、時々、すべてのページをページングできなくなりました。)。

他にこのような問題に遭遇している人はいますか、または、この原因について何か心当たりがありますか。

どのように解決するのですか。

最終的に解決策を見つけることができました。どうやら私たちの実装には 2 つの問題があるようです。

  1. のビューを削除しないことです。 destroyItem() .
  2. でビューを削除していなかったので、レイアウトを一度だけ膨らませるためにビューをキャッシュしていました。 destroyItem() でビューを削除しておらず、また instantiateItem() で追加するのではなく、単に現在の位置に対応するキャッシュされたビューを返していただけなのです。

のソースコードをあまり深く見ていないのですが、このように ViewPager - のソースコードを深く見ていないため、そうしなければならないことが明示されているわけではありませんが、docs には :

destroyItem()

与えられた位置のページを削除します。アダプタは、コンテナからビューを削除する責任を負いますが、 finishUpdate(ViewGroup)から戻るまでにこれが行われることを保証するだけでなければなりません。

とします。

<ブロッククオート

非常にシンプルな PagerAdapter は、ページビュー自体をキーオブジェクトとして使用し、作成後に instantiateItem(ViewGroup, int) からそれらを返し、それらを親 ViewGroup に追加することを選択するかもしれません。一致する destroyItem(ViewGroup, int, Object) の実装は、親 ViewGroup から View を削除し、 isViewFromObject(View, Object) は、 return view == object; として実装することができます。

ということで、私の結論は ViewPager の子プロセスを明示的に追加/削除するには、その基礎となるアダプタに依存します。 instantiateItem() / destroyItem() . つまり、もしあなたのアダプタが PagerAdapter のサブクラスである場合、サブクラスはこのロジックを実装しなければなりません。

補足: 注意すべきは この の中でリストを使っている場合は ViewPager .