片段中未调用 onAttach()
Posted
技术标签:
【中文标题】片段中未调用 onAttach()【英文标题】:onAttach() not called in Fragment 【发布时间】:2015-12-12 19:13:43 【问题描述】:我的 Fragment 从 AppCompatActivity
启动时没有调用 onAttach(context)
方法。
在 XML 中创建片段:
<fragment
android:id="@+id/toolbar"
class="package.MainToolbarFragment"
android:layout_
android:layout_
tools:layout="@layout/fragment_main_toolbar" />
但如果我从support.v4.Fragment
扩展它,onAttach(context)
调用!
可能是什么问题?
当然,我可以从v4.Fragment
扩展所有片段,但我不想要它。这是不好的做法吗?
还有项目 min sdk 14。
【问题讨论】:
我认为你应该访问这里***.com/questions/32083053/…希望它澄清。 【参考方案1】:它没有被调用,因为这个方法已经被添加到 API 23 中。如果你在使用 API 23 (marshmallow) 的设备上运行你的应用程序,那么onAttach(Context)
将被调用。在所有以前的 Android 版本上,onAttach(Activity)
将被调用。
http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity)
支持库片段独立于平台。因此它适用于所有 API 版本。
【讨论】:
知道我是否应该同时实现它们(对于 api 23 设备)?在 API 23 中是否仍在调用 onAttach(Activity)? @sockeqwe 向你致敬。我错误地导入了新的 Fragment 类,看了几个小时却没有注意到。谢谢 @AvivBenShabat 您应该使用此 API 的应用兼容版本并仅实现该方法的 onAttach(Context context) 版本 现在你应该使用androix
片段。【参考方案2】:
虽然 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
是比Context
(作为子类)更专业,因此将优先。
【讨论】:
使用支持库还不错。您的方法会导致一些奇怪的行为,例如每次都不会调用 onStart()。 @yehe 也许您可以详细说明支持库除了实现这两种方法之外还做了什么?我将其视为一个包含一些主题和新版本闪光的主要 polyfil 修复程序包,以使旧设备焕然一新。我并不是说这很糟糕,只是当我在 Android 上使用框架时,它大多是无关紧要的。 根据我的经验,实现两种方法在许多设备上都不起作用。已在各种 Nexus、三星手机上进行过测试,其中许多手机都无法使用。调试显示 onAttach(Activity activity) 不会每次都被调用。使用支持库,我从未遇到任何奇怪的错误。【参考方案3】:除了前面提到的 cmets,我认为需要注意的是,如果您尝试使用 onAttach()
从父 Activity 更新 Fragment 中包含的数据,则在收集时可能会遇到问题当片段膨胀时,Activity 内部的变量为 null 或为空。在 Activity 生命周期的某个时刻,您的数据模型可能会发生变化,需要在片段内进行更新。您可能会尝试获取对已经膨胀的片段的引用,但是当您单步执行代码时会发现 onAttach()
永远不会触发,即使使用包含 Context 或 Activity 对象的覆盖也是如此。
如果您尝试为片段创建侦听器并从onAttach()
回调方法初始化侦听器,onAttach()
将不会触发,除非您在将片段添加到 Activity 时提供如下所示的 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);
【讨论】:
以上是关于片段中未调用 onAttach()的主要内容,如果未能解决你的问题,请参考以下文章
Dagger 2:在片段中调用onAttach之前,注入的对象可能仍为null
在 onActivityCreated() 之后再次调用 Fragment 的 onAttach()
是否最好使用 Activity.onAttachFragment 或 Fragment.onAttach 在 Activity 和嵌套片段之间进行通信?