片段中的 getMapAsync()

Posted

技术标签:

【中文标题】片段中的 getMapAsync()【英文标题】:getMapAsync() in Fragment 【发布时间】:2016-05-31 12:08:42 【问题描述】:

我在 Fragment 中实现 Google 地图时遇到问题。

这是我的片段类的一部分:

public class FragmentStoreFinderMap extends Fragment implements OnMapReadyCallback 

// Google Map
private GoogleMap googleMap;
private int i;
@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

        googleMap = ((SupportMapFragment)getActivity().getSupportFragmentManager().findFragmentById(
              R.id.map)).getMapAsync(this);

我在 getMapAsync(this) 中遇到错误。我告诉不兼容的类型。

上面写着:

必需:com.google.android.gms.map.GoogleMap

发现:无效

顺便说一句,这是我的 xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<fragment class="com.google.android.gms.maps.SupportMapFragment"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_
    android:layout_/>

</LinearLayout>

【问题讨论】:

【参考方案1】:

在你的 XML 布局中你应该这样做

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_>

<com.google.android.gms.maps.MapView
    android:id="@+id/map"
    android:layout_
    android:layout_/>

</FrameLayout>

在你的片段中实现这个

private MapView mapView;
private GoogleMap googleMap;

如果没有 onCreateView 则覆盖 onCreateView,就像下面的代码一样

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.your_layout, container, false);

覆盖 onViewCreated() 里面 onViewCreated() 放这个

mapView = (MapView) view.findViewById(R.id.map);
mapView.onCreate(savedInstanceState);
mapView.onResume();
mapView.getMapAsync(this);//when you already implement OnMapReadyCallback in your fragment

当你已经在你的片段中实现 OnMapReadyCallback 时,把这个/代码像这样

@Override
public void onMapReady(GoogleMap map) 
    googleMap = map;

希望对你有所帮助。

【讨论】:

你应该重写 onCreateView 并像这样膨胀你的布局。 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) // 为这个片段膨胀布局 return inflater.inflate(R.layout.your_layout, container, false); 您是否覆盖了片段中的 onViewCreated ? 为什么需要调用onCreate(savedInstanceState);和 onResume(); ? 你为什么在onViewCreated()中打电话给mapView.onResume();?为什么不在onResume() 我无法实现 onMapReadyCallBack ..它显示无法解决【参考方案2】:

在我脑子里有些过热之后,感谢这篇文章和https://***.com/a/34732804/3925554,我想说目前有两种方法可以将 MapFragment 添加到您的应用程序中:

<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
class="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_
android:layout_/>

通过这种方式,您必须使用标准片段并在内部实现它。实际上,您正在将一个片段插入另一个片段:

    @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) 
    super.onViewCreated(view, savedInstanceState);
    
    SupportMapFragment supportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
    supportMapFragment.getMapAsync(this);

另一种方法是扩展真正的 SupportMapFragment 并以这种方式实现它,而不需要 xml:

    @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) 
    super.onViewCreated(view, savedInstanceState);

    getMapAsync(this);

而且它们无需在onCreateView 中设置布局即可工作,也无需在onViewCreated() 中手动调用mapView.onCreate(savedInstanceState);mapView.onResume();,无论如何不推荐这样做。

希望对你有帮助!

【讨论】:

您的 onViewCreated 方法对我有用。这里重要的部分是使用子片段管理器,而不是父片段管理器 但是我说的是我推荐第二种情况。如果您的片段扩展了SupportMapFragment,则您不需要FragmentManager,并且您不必使用布局在另一个片段中膨胀。【参考方案3】:
 SupportMapFragment mMapFragment = SupportMapFragment.newInstance();
 FragmentTransaction fragmentTransaction =
 getChildFragmentManager().beginTransaction();
 fragmentTransaction.add(R.id.flMap, mMapFragment);
 fragmentTransaction.commit();
 mMapFragment.getMapAsync(this);

【讨论】:

【参考方案4】:

您的代码返回此错误,因为getMapAsync() 没有返回任何内容。如果您查看此功能的文档:

public void getMapAsync(OnMapReadyCallback 回调)

设置一个回调对象,当 GoogleMap 实例已准备好使用。

注意:

这个方法必须从主线程调用。回调将是 在主线程中执行。如果 Google Play 服务是 未安装在用户设备上,不会触发回调 直到用户安装它。在极少数情况下 GoogleMap 是 创建后立即销毁,不会触发回调。 回调提供的 GoogleMap 对象不为空。

OnMapReadyCallback 是一个接口,需要通过这个函数实现和传递。当前没有为您的 googleMap 变量分配任何内容,您应该在此代码块中设置其值 implements OnMapReadyCallback

@Override
    public void onMapReady(GoogleMap googleMap) 
        this.googleMap = googleMap;


    

此代码应该在您的 Fragment 某处。由于您的 Fragment 已经实现了此接口,因此您可以将其作为 this 传递。

【讨论】:

我的课堂上已经有了 onMapReady。顺便说一句,谢谢你的回答,

以上是关于片段中的 getMapAsync()的主要内容,如果未能解决你的问题,请参考以下文章

MapFragment 在 getMapAsync(this) 方法中导致 NullPointerException

以编程方式将 GoogleMap 添加到片段

另一个片段内的谷歌地图 - 像 onLocationChanged 这样的功能不起作用

安卓。通过从片段中的按钮调用片段中的方法来关闭片段?

片段中的片段

片段对话框中的片段膨胀引发错误“片段未创建视图”