SupportMapFragment 的 findFragmentById 在 Android Studio 中返回 null
Posted
技术标签:
【中文标题】SupportMapFragment 的 findFragmentById 在 Android Studio 中返回 null【英文标题】:findFragmentById for SupportMapFragment returns null in Android Studio 【发布时间】:2014-12-23 04:45:29 【问题描述】:最近我将一个项目从 Eclipse 迁移到 android Studio。除了我的一个使用 SupportMapFragment 的片段外,一切都设置好了并且工作正常。下面的 findFragmentById(在 Eclipse 中构建时有效)现在返回 null :(
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
SupportMapFragment m = ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.safety_map));
xml的sn-p...
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:orientation="vertical" >
<fragment
android:id="@+id/safety_map"
android:layout_
android:layout_
android:layout_marginBottom="40dp"
map:cameraTargetLat="@string/livesafe_latitude"
map:cameraTargetLng="@string/livesafe_longitude"
map:uiZoomControls="false"
class="com.google.android.gms.maps.SupportMapFragment"/>
这是我在 build.gradle 中的依赖项:
dependencies
//google analytics
compile 'com.google.apis:google-api-services-analytics:v3-rev103-1.19.0'
//support library for api 10
compile 'com.android.support:support-v4:21.0.0'
//google play services
compile 'com.google.android.gms:play-services:6.1.11'
compile project(':facebook')
compile files('libs/android-support-multidex.jar')
compile files('libs/aws-android-sdk-1.6.0-debug.jar')
compile files('libs/FlurryAnalytics_3.3.2.jar')
我没有更改之前在 Eclipse 中工作的 xml 文件或 Fragment 类中的任何代码。
【问题讨论】:
什么是lsActivity?你可以试试 getActivity() 吗? 尝试使用 getActivity() 但没有运气.... lsActivity 仅用于 bc 我所有的活动都扩展了一个 Common ,这样我就不必到处打字了。 lsActivity = (MyActivity) getActivity();编辑我的问题以避免给其他人造成混淆 先生,请执行此操作,只是一个回调测试.. 复制该代码并将其放入片段生命周期的 onresume() 中.. 如果它不返回 null,那么它将是一个回调 lil问题,如果确实发生了,请直接从您的 oncreatview 方法中调用它并从膨胀的布局中获取 id..直接..希望它对您有所帮助.. OK 进入 onResume() 也会导致 null 。您能否更具体地使用“直接从膨胀布局中获取 id”? 【参考方案1】:从您覆盖Fragment.onActivityCreated()
的事实来看,我认为您包含地图片段的布局就是您的Fragment
的布局。在这种情况下,SupportMapFragment
是您托管 Fragment
的 子 片段。当您尝试检索它时,您使用的是Activity
FragmentManager
。你应该改用你的Fragment
的FragmentManager
:
例如,这个:
SupportMapFragment m = ((SupportMapFragment) getActivity()
.getSupportFragmentManager().findFragmentById(R.id.safety_map));
变成:
SupportMapFragment m = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.safety_map));
【讨论】:
Activity的片段管理器管理Activity的直接片段。每个片段都有自己的 FragmentManager 来管理该片段的子片段。因此,您的 Activity 在管理器中包含您的地图托管片段。该地图托管片段在 其 管理器中包含 SupportMapFragment。 令人困惑的是,从FragmentActivity
你需要使用getSupportFragmentManager()
。但是,从Fragment
,getFragmentManager()
将呼叫到getActivity().getSupportFragmentManager()
。要获得Fragment
的经理,您应该从Fragment
调用getChildFragmentManager()
。
感谢 cmets。我们有赢家!我设置了一个断点并尝试了所有三个... getFragmentManager()、getActivity().getSupportFragmentManager() 和 getChildFragmentManager()。唯一有效的是 getChildFragmentManager()。我更新到 targetSdkVersion 21 也许这就是我以前的内容不再有效的原因。谢谢 :)
天啊!是的,这也发生在我身上!先生,你让我很开心!抱歉 ***,我知道我不应该在评论中说谢谢,但这太重要了!!!
多么精彩的解释。我想知道为什么这对 Fragments 但 Activity 不起作用!我也尝试了 Breakpoints 并得出结论,getChildFragmentManager() 是正确的实现,因为它解决了 支持 Fragment inside Fragment。拯救了我的一天!【参考方案2】:
是的。它不适用于 targetSdkVersion 21,如果您的 Map 片段是片段的内部部分(由于某些问题,提到了 this 和 this)。
临时解决可以建议这样的技巧:
public class MyFragment extends Fragment
private SupportMapFragment fragment;
private GoogleMap map;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
return inflater.inflate(R.layout.layout_with_map, container, false);
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null)
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment).commit();
【讨论】:
为什么这是一个临时解决方案? @BartaTamás 这是一个错误,我认为它很快就会修复。但它仍然没有修复。 (参见上面的参考资料) 谢谢,我明白了。我认为这是 Google 人员的设计决定。 @TamásBarta 不是我的朋友,这是他们设计决策中的一个错误!【参考方案3】:以下代码对我有用。我在Fragment
中使用谷歌地图:
SupportMapFragment m = ((SupportMapFragment) getChildFragmentManager() .findFragmentById(R.id.safety_map));
【讨论】:
【参考方案4】:所有答案都以各自的方式正确。您可能会遵循某人的 Java 代码,该代码对他们有用但对您不起作用,因为您的 xml 代码中的实现与他们不同。
所以让我告诉你我是如何设法在 Activity
和 Fragment
中加载地图的
活动:
<fragment
android:name="com.google.android.gms.maps.MapFragment"
android:id="@+id/map"
android:layout_
android:layout_/>
Java 类:
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
在片段中:
<fragment
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/map"
android:layout_
android:layout_/>
Java 类:
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
【讨论】:
getChildFragmentManager 不适用于 SupportMapFragment。它告诉我“无法解析方法”。以上是关于SupportMapFragment 的 findFragmentById 在 Android Studio 中返回 null的主要内容,如果未能解决你的问题,请参考以下文章
SupportMapFragment vs MapFragment性能方面
使用 SupportMapFragment 时,我如何知道地图已准备好使用?
SupportMapFragment 的 findFragmentById 在 Android Studio 中返回 null