【问题标题】:getMapAsync() in Fragment片段中的 getMapAsync()
【发布时间】: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_width="match_parent"
android:layout_height="match_parent"
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_width="match_parent"
    android:layout_height="match_parent"/>

</LinearLayout>

【问题讨论】:

    标签: android google-maps android-fragments android-studio supportmapfragment


    【解决方案1】:

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

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <com.google.android.gms.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
    </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://stackoverflow.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_width="match_parent"
    android:layout_height="match_parent"/>
    

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

        @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。顺便说一句,谢谢你的回答,
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 2011-10-14
      相关资源
      最近更新 更多