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 片段。当您尝试检索它时,您使用的是ActivityFragmentManager。你应该改用你的FragmentFragmentManager

例如,这个:

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()。但是,从FragmentgetFragmentManager() 将呼叫到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 代码中的实现与他们不同。

所以让我告诉你我是如何设法在 ActivityFragment 中加载地图的

活动:

 <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 时出错

SupportMapFragment vs MapFragment性能方面

使用 SupportMapFragment 时,我如何知道地图已准备好使用?

SupportMapFragment 的 findFragmentById 在 Android Studio 中返回 null

为啥 Fragment SupportMapFragment 还没有附加

如何在 SupportMapFragment 中使用 OSMDroid 在地图上启用 LongClick