13

実際、私は常に次のようにフラグメントでビューを再利用しました。

private View mView = null;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    if (mView == null)
        mView = inflater.inflate(R.layout.view);
    return mView;
}

ビューページャーなどでうまくいきました。これで、単純なアクティビティでもフラグメントを使用し始めました。フラグメントをバックスタックに追加した場合にのみ、これは失敗します。java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

だから私の質問は:

  • ビューの親を確認し、それを削除して新しい親に追加しても問題ありませんか?
  • または、常にビューを再作成し、再利用しないようにする必要がありますか? はいの場合、なぜですか?
  • ビューの再利用が失敗する他のポイントはありますか?
4

3 に答える 3

14

たぶん、これは動作を理解するのに役立ちます。FragmentManagerImpl.javaを調べると、次のことがわかります。

最初に呼び出してビューを作成しonCreateView()( 845 行目)、作成したビューを別のビューでラップし、それがビューの親になります ( 848 ~ 849 行目)。これは、ビューが実際のコンテナーの子になるのではなく、ラッパー ビューの子になることを意味します。ビューがコンテナーから削除されると、再利用の問題が発生します (行 998 )。FragmentManager はコンテナーからラッパー ビューを削除しますが、実際のビューは親ラッパー ビューに追加されたままです。これが、発生する問題の原因です。

したがって、ビューをその親から削除すると、機能する可能性があります。これを知っていても、フラグメントが破棄された後でも「消える」アニメーションで使用できるため、ビューはフラグメントよりも少し長く存続する可能性があるため、フラグメント内のビューを再利用することはお勧めしません。その時点でそのようなビューをその親から削除しようとすると、アニメーションが壊れる可能性があります。

ビューをキャッシュしないもう 1 つの理由は、Android は設計上、フラグメントでのビューのリサイクルをサポートしていないということです。ListAdapterビューの再利用を許可したことを覚えていますか? Android は、これらのビューのキャッシュと適切な再利用を処理します。ただし、これはフラグメントには当てはまりません。

于 2013-09-05T14:36:32.190 に答える