web-dev-qa-db-ja.com

onAttach()はFragmentで呼び出されません

フラグメントは、AppCompatActivityから起動したときにonAttach(context)メソッドを呼び出しません。

XMLで作成するフラグメント:

_<fragment
    Android:id="@+id/toolbar"
    class="package.MainToolbarFragment"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    tools:layout="@layout/fragment_main_toolbar" />
_

ただし、_support.v4.Fragment_から拡張すると、onAttach(context)呼び出し!

何が問題なのでしょうか?

もちろん、_v4.Fragment_からすべてのフラグメントを拡張できますが、それは望ましくありません。それは悪い習慣ですか?また、プロジェクトの最小SDK 14。

61
winston

このメソッドはAPI 23に追加されているため、呼び出されません。API23(Marshmallow)を備えたデバイスでアプリケーションを実行すると、onAttach(Context)が呼び出されます。以前のすべてのAndroid Versions onAttach(Activity)が呼び出されます。

http://developer.Android.com/reference/Android/app/Fragment.html#onAttach(Android.app.Activity)

サポートライブラリフラグメントはプラットフォームに依存しません。したがって、すべてのAPIバージョンで機能します。

128
sockeqwe

Googleは廃止されたAPIの使用を停止することを望んでいますが

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    ...

非常に新しいため、広く呼ばれていません。また、実装する必要があります

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    ...

私にとっては同じですが、 [〜#〜] kiss [〜#〜] が好きで、別のサポートライブラリを導入すると、apkが約1000kbに​​倍増する傾向があります。昨日、SDKを更新しただけです。

多くの場合、タイプがここで交換可能でない理由は、Activityがパブリックに表示されていると同時にActivityが提供されると、Activityをとるメソッドが呼び出されるためです。 [$ var] _は(サブクラスとして)Contextよりも特殊化されているため、優先されます。

43
John

前述のコメントに加えて、onAttach()を使用して親アクティビティからフラグメント内に含まれるデータを更新しようとすると、次の場合に問題が発生する可能性があることに注意することが重要です。フラグメントが膨張している場合、アクティビティ内のコレクション変数はnullまたは空です。アクティビティのライフサイクル内のある時点で、データモデルが変更される可能性があり、フラグメント内で更新する必要があります。すでに膨らんだフラグメントへの参照を取得しようとするかもしれませんが、コードをステップ実行すると、ContextまたはActivityオブジェクトを含むオーバーライドを使用している場合でも、onAttach()が実行されないことがわかります。

フラグメントのリスナーを作成し、onAttach()コールバックメソッドからリスナーを初期化しようとしている場合、フラグメントを追加するときに以下に示すタグパラメーターを指定しない限り、onAttach()は起動しません。アクティビティへ:

// in the Activity
getFragmentManager().beginTransaction()
    .add(
        R.id.fragmentContainer,
        CustomFragment.newInstance(customDataSource),
        CustomFragment.TAG // Must be passed in for the code below to work
    ).commit();


// Getting a reference to the fragment later on (say to update your data model inside the fragment (in onActivityResult())

CustomFragment fragmentDelegate = (CustomFragment) getFragmentManager().findFragmentByTag(CustomFragment.TAG);
fragmentListener.updateDataSource(customDataSource);
0
mrfilter