フラグメントでのonCreateViewとonViewCreatedの違い


118

これら2つの方法の本質的な違いは何ですか?TextViewを作成するとき、パフォーマンスを向上させるためにどちらを使用する必要がありますか?

編集:との違いは何ですか

onCreateView() {
  root = some view
  View v = new View(some context);
  root.add(v);
  return root;
}


onViewCreated() {
  View v = new View(some context);
  getView().add(v);
}

混乱を説明するために編集を追加しました。1つの方法が次々と続く場合、なぜ2つあるのですか?上記のように、すべてのビュー作成を単一のメソッド内で行うことはできませんか?
スミス

7
グーグルして推測する必要がある場合は、おそらく不適切な名前のメソッドがあります。
バラージュネメス

回答:


85

でビューの初期化中にクラッシュが発生しましたonCreateView

でレイアウトを膨らませるonCreateView必要がありますがfindViewById、in を使用して他のビューを初期化しないでくださいonCreateView

ビューが正しく初期化されない場合があるためです。したがって、常に(ビューが完全に作成されている場合)で使用findViewByIdonViewCreated、ビューをパラメーターとして渡します。

onViewCreated ビューが完全に作成されたことを確認します。

onViewCreated androidドキュメント

onCreateViewandroid.view.LayoutInflater, android.view.ViewGroupandroid.os.Bundle)が戻った直後、ただし保存された状態がビューに復元される前に呼び出されます。これにより、サブクラスは、ビュー階層が完全に作成されたことがわかると、初期化する機会が与えられます。ただし、フラグメントのビュー階層は、この時点では親に関連付けられていません。


4
ありがとう。私もこの問題に直面し、コンポーネントを使用しました。post(...)表示されるまで待機するメソッド。おそらくfindViewByIdとその他の初期化を行いonViewCreatedます。
CoolMind 2016年

22
そのテキストはどこから引用されたのですか?公式ドキュメントでは見つかりませんでした。
ダニエル

ここで引用された声明の開発者サイトからの参照を投稿していただけますか?
Namrata Bagerwal

4
これは実際には正しくありません。onCreateViewでビューを見つけることができますが、ビューをインフレートした後でのみ、すでにインフレートしたビューからのみです。Fragment.findViewById()は安全ではありませんが、フラグメントビューを既に拡張している場合、View.findViewById()は安全です。
colintheshots

46

onViewCreatedonCreateView(を含むすべてのオブジェクトを初期化および作成するメソッド)の直後に呼び出されるTextViewため、パフォーマンスの問題はありません。

開発者サイトから:

onViewCreated(ビューの表示、バンドルのsavedInstanceState)

onCreateView(LayoutInflater、ViewGroup、Bundle)が戻った直後、ただし保存された状態がビューに復元される前に呼び出されます。これにより、サブクラスは、ビュー階層が完全に作成されたことがわかると、初期化する機会が与えられます。ただし、フラグメントのビュー階層は、この時点では親に関連付けられていません。

ソース:Fragment#onViewCreated


28

のフィールドにサブビューを割り当てることをお勧めしますonViewCreated。これは、フレームワークが自動的にnullチェックを行い、フラグメントのビュー階層が作成され、(XMLレイアウトファイルを使用している場合)適切に拡張されているためです。

コードスニペット:FragmentManger.java

// This calls onCreateView()
f.mView = f.performCreateView(f.getLayoutInflater(f.mSavedFragmentState), null, f.mSavedFragmentState);

// Null check avoids possible NPEs in onViewCreated
// It's also safe to call getView() during or after onViewCreated()
if (f.mView != null) {
    f.mView.setSaveFromParentEnabled(false);
    if (f.mHidden) f.mView.setVisibility(View.GONE);
    f.onViewCreated(f.mView, f.mSavedFragmentState);
}

6
また、ビュー階層のインフレーション/作成ロジックから初期化ロジックを分離します
orangemako

1
これは興味深いです。なぜこのアプローチの方が優れているかについて、追加のリソースはありますか?つまり、すべてのonCreateViewメソッドは、「return inflater.inflate(R.layout.layout_file、container、false);」のみで構成されている必要があるということですか。およびonviewcreatedには、すべての「findViewById」メソッドが必要ですか?これによりどのようなパフォーマンスの向上がもたらされますか?移行が速くなりますか?
android_student 2015

最初の質問に答えるために、onCreateViewを使用してフラグメントのビュー階層を作成します。これは、XMLインフレーションまたは動的作成(つまり、Javaビューをプログラムで作成)を介して行うことができます。だからあなたはまったく電話inflateしないかもしれません。ただし、フラグメントにUI要素が必要な場合は、親ビューを返す必要があります。それ以外の場合は戻りnullます。
Orangemako 2015

パフォーマンスの向上はまったくありません。見てみるFragmentManagerためとフラグメントのコードperformCreateView呼び出し、onCreateView github.com/android/platform_frameworks_base/blob/...を、あなたがのためにカントーいくつかのことを保証されているonViewCreatedライフサイクル・コールバック:
orangemako

1.フラグメントがその親アクティビティに動的に追加されている場合、ビュー階層がコンテナにアタッチされます。2. NPEを気にすることなく、安全にビュールックアップを実行できます。3.私はアニメーションにはあまり詳しくありませんが、フラグメントの遷移はすでに開始されています(つまり、UIスレッドのメッセージキューに送信されます)。
Orangemako

13

onCreateView膨張したビューを返します。OnViewCreated直後に呼び出されonCreateView、getは膨張ビューのパラメーターを持ちます。その戻り型はvoid


1
混乱を説明するために編集を追加しました。1つの方法が次々と続く場合、なぜ2つあるのですか?上記のように、すべてのビュー作成を単一のメソッド内で行うことはできませんか?
スミス

3
onCreateViewはすぐに戻ります。OnViewCreateを使用して、初期化などを実行できます。すでに述べたように、onViewCreatedには、パラメーターとして、onCreateView内で膨張したビューがあります。だからあなたはgetView電話を避けることができます
Blackbelt 2014

8

onCreateView()はフラグメントと同等のonCreate()アクティビティであり、ビューの作成に実行さます。ビューが作成された後に
onViewCreated()実行されます。

should I use one over the other for performance? いいえ。パフォーマンスが向上したという証拠はありません。

実際にonCreate()はFragmentsにもメソッドがありますが、めったに使用されませ(私はそれを使用したことはなく、適切なユースケースを見つけていません)。

私は常にonCreateView()Fragmentsの代わりとして使用しonCreate()ます。
そして、私はそれに満足しています。


2
@npace、なぜ?またonCreateView、はActivityのと同等だと思いますonCreate
CoolMind 2016年

2
@CoolMindええ、nPaceは完全に間違っているわけではありませんonCreate()。フラグメントにもメソッドがあるからです。しかし、それ使用されていません(または、少なくとも私は使用していませ)。私は常にonCreateView()Fragmentsの代わりに使用します。
Phantômaxx

1
@Rotwang、同意します!一部のチュートリアルでは、onCreateを使用してsetHasOptionsMenu(true)を配置していますが、onCreateViewまたはonViewCreatedで行う方がよいと思います。
CoolMind

1
@CoolMind完全に同意します。多分私は私の答えに間違った言葉を使った。
Phantômaxx

1
@Rotwang、あなたは正しく言った。フラグメントを初めて使用したとき、onCreateが使用されない理由もわかりませんでした。
CoolMind 2016年

4

Fragment.onCreateView()のところドキュメントは言う:

このメソッドのレイアウトのみを拡張し、返されたビューで動作するロジックをonViewCreated(View、Bundle)に移動することをお勧めします。

理由を理解する必要はありません。ドキュメントが言うように行う必要があるだけですが、この推奨事項が存在する理由を知ることは興味深いでしょう。私の推測は懸念の分離ですが、私見ではこれにより、必要以上に複雑になります。


理由が懸念の分離である場合、ActivityはなぜレイアウトをsetContentView()インフレートするのonCreate()ですか?
MinhNghĩa

@MinhNghĩa良い点。その質問に対する答えは、異なるプログラマーが異なる方法で設計した(フラグメントはAndroidを最初に入手してから数年後に導入された)が、誰が知っているかということです。
Peppe LG

2

私が使用する主な理由onViewCreatedは、初期化ロジックを、ビュー階層のインフレーション/作成ロジックから分離するためonViewCreateです。他のすべてのパフォーマンス特性は同じに見えます。


2

これらの主な違いは、kotlin.in onCreateView()を使用するときに、xmlファイルのビューにアクセスするたびfindViewByIdを使用する必要があると思いますが、onViewCreatedでは、idを呼び出すだけでビューにアクセスできます。


これは本当ですか?どちらかの方法でコードでIDを使用した場合、ビューのnullが取得されます。常にfindViewByIdを使用する必要があります。
ジムリースク2018

1
いいえ、そうではありません。oncreateviewはビューをインスタンス化し、oncreateviewの後で、保存された状態が復元される前に呼び出されます...これは、フラグメントのライフサイクルにおけるタイミングの問題です
me_

1

onCreateViewは、レイアウトを作成してビューを拡張するためにフラグメントで使用されます。onViewCreatedは、上記の方法で作成されたビューを参照するために使用されます。最後に、onActivityCreatedでアクションリスナーを定義することをお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.