onAttach()未在Fragment中调用

时间:2015-09-16 09:23:14

标签: android android-fragments android-activity android-support-library fragmentmanager

我的片段在从onAttach(context)启动时不会调用AppCompatActivity方法。

以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.FragmentonAttach(context)致电!

延长它

可能是什么问题?

当然,我可以扩展v4.Fragment的所有片段,但我不想要它。这是不好的做法吗? 同时项目min sdk 14。

3 个答案:

答案 0 :(得分:128)

由于此方法已在API 23中添加,因此未调用它。如果在具有API 23(marshmallow)的设备上运行应用程序,则将调用onAttach(Context)。在以前的所有Android版本中,都会调用onAttach(Activity)

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

支持库片段与平台无关。因此它适用于所有API版本。

答案 1 :(得分:43)

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的方法,因为它们都是公开可见的ActivityContext(作为子类)更专业,因此优先。

答案 2 :(得分:0)

除了上述评论之外,我认为重要的是要注意,如果您尝试使用onAttach()来更新来自父Activity的片段中包含的数据,则可能会遇到问题。当片段膨胀时,Activity内的集合变量为null或为空。在Activity的生命周期内的某个时刻,您的数据模型可能会发生变化,需要在片段内进行更新。您可能尝试获取对已经膨胀的片段的引用,但是当您逐步执行onAttach()永远不会触发的代码时,即使使用包含Context或Activity对象的覆盖,也会查找。

如果您尝试为片段创建侦听器并从onAttach()回调方法初始化侦听器,则onAttach()将不会触发,除非您在添加片段时提供如下所示的tag参数活动:

// 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);