【问题标题】:onMapReady is not called in the fragment片段中未调用 onMapReady
【发布时间】:2016-09-16 20:28:15
【问题描述】:

我正在构建一个与谷歌地图相关的应用程序。在这个我试图在片段中实现地图。我在 OnMapReady 方法中操作地图。但是应用程序没有调用 OnMapReady 方法。我在活动中实现了同样的事情并且它的工作完美。但它不能在片段中工作。我不知道它是否是片段生命周期的问题,我错过了一些东西。 这是代码。

Maps_Fragment.java

    package com.example.mudasir.login;


import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.IOException;
import java.util.List;


/**
 * A simple {@link Fragment} subclass.
 */
public class Maps_Fragment extends Fragment implements OnMapReadyCallback {

    public GoogleMap mMap;
    String[] showroom_addresses = new String[5];
    List<Address> addressList = null;
    LatLng latlng;
    LatLngBounds.Builder builder  = new LatLngBounds.Builder();
    View view1;

    public Maps_Fragment() {
        // Required empty public constructor
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_maps_, container, false);
    }
    @Override
    public void onViewCreated(View view,Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.maps);
        mapFragment.getMapAsync(this);
    }
    @Override
    public void onMapReady(GoogleMap googleMap) {

        showroom_addresses[0] = "Dubai";
        showroom_addresses[1] = "Fujairah";
        showroom_addresses[2] = "Al Ain";
        showroom_addresses[3] = "Sharjah";
        showroom_addresses[4] = "Ras Al Khaimah";
        Geocoder geocoder = new Geocoder(getActivity());
        for(int i =0; i<5; i++) {
            try {
                addressList = geocoder.getFromLocationName(showroom_addresses[i], 1);
            } catch (IOException e) {
                e.printStackTrace();
            }
            android.location.Address address = addressList.get(0);
            latlng = new LatLng(address.getLatitude(), address.getLongitude());
            Marker marker = googleMap.addMarker(new MarkerOptions().position(latlng).title(showroom_addresses[i]));
            builder.include(marker.getPosition());
        }

        LatLngBounds bounds = builder.build();
        int padding = 0;
        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds,padding);
        //CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new MarkerOptions().position(latlng).title(showroom_addresses[3]).getPosition(),7F);
        googleMap.animateCamera(cu);
    }

}

Maps_Fragment.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"
    tools:context="com.example.mudasir.login.Maps_Fragment">

    <!-- TODO: Update blank fragment layout -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout">


        <fragment android:id="@+id/maps"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.MapFragment"
            android:layout_alignParentTop="true">
            </fragment>

相同的方法和要求在活动的情况下工作正常,但在片段的情况下出现问题。请帮忙。

【问题讨论】:

    标签: java android google-maps android-fragments fragment-lifecycle


    【解决方案1】:

    你必须从

    扩展
    SupportMapFragment
    

    而不是

    Fragment
    

    [已编辑]

    我的建议是使用 2 个片段:一个在您没有任何结果时使用,另一个使用 SupportFragmentManager。

    另外,在应该从 SupportFragmentManager 扩展的 Maps_Fragment 中,您必须删除 onCreateView 和 onViewCreated 的覆盖,否则您应该管理所有 SupportMapFragment,我认为您不想这样做。

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_maps_, container, false);
        }
        @Override
        public void onViewCreated(View view,Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.maps);
            mapFragment.getMapAsync(this);
        }]
    

    要实现 OnMapReadyCallback,我会在 onActivityCreated 方法中实现:

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getMapAsync(this);
    }
    

    【讨论】:

    • 现在代码正在运行,但它在 mapFragment.getMapAsync(this); 上给出了 nulll 异常;并且应用程序正在崩溃。
    【解决方案2】:

    实现这一点的更好方法是使用 MapView 而不是 MapFragment。并执行以下操作

    <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"
    tools:context="com.example.mudasir.login.Maps_Fragment">
    
        <!-- TODO: Update blank fragment layout -->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/linearLayout">
    
            <com.google.android.gms.maps.MapView
                android:id="@+id/mapView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </RelativeLayout>
    
    </FrameLayout>
    

    还有你的 Maps_Fragment.java 类

    public class Maps_Fragment extends Fragment implements OnMapReadyCallback {
    
        private View view;
        private MapView mapView;
        String[] showroom_addresses = new String[5];
        List<Address> addressList = null;
        LatLng latlng;
        LatLngBounds.Builder builder  = new LatLngBounds.Builder();
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.fragment_maps_, container, false);
    
            // Gets the MapView from the XML layout and creates it
            mapView = (MapView) view.findViewById(R.id.mapView);
            mapView.onCreate(savedInstanceState);
    
            // Set the map ready callback to receive the GoogleMap object
            mapView.getMapAsync(this);           
    
            return view;
        }
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
    
            // Need to call MapsInitializer before doing any CameraUpdateFactory calls
            try {
                MapsInitializer.initialize(this.getActivity());
            } catch (GooglePlayServicesNotAvailableException e) {
                e.printStackTrace();
            }
    
            mGoogleMap = googleMap;
    
            showroom_addresses[0] = "Dubai";
            showroom_addresses[1] = "Fujairah";
            showroom_addresses[2] = "Al Ain";
            showroom_addresses[3] = "Sharjah";
            showroom_addresses[4] = "Ras Al Khaimah";
            Geocoder geocoder = new Geocoder(getActivity());
            for(int i =0; i<5; i++) {
                try {
                    addressList = geocoder.getFromLocationName(showroom_addresses[i], 1);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                android.location.Address address = addressList.get(0);
                latlng = new LatLng(address.getLatitude(), address.getLongitude());
                Marker marker = mGoogleMap.addMarker(new MarkerOptions().position(latlng).title(showroom_addresses[i]));
                builder.include(marker.getPosition());
            }
    
            LatLngBounds bounds = builder.build();
            int padding = 0;
            CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds,padding);
            //CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new MarkerOptions().position(latlng).title(showroom_addresses[3]).getPosition(),7F);
            mGoogleMap.animateCamera(cu);
        }
    
        @Override
        public void onResume() {
            mapView.onResume();
            super.onResume();
        }
    
        @Override
        public void onDestroyView() {
            super.onDestroy();
            mapView.onDestroy();
        }
    }
    

    请确保您有以下 Fragment 和 Map 的导入

    import android.support.v4.app.Fragment;
    
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.MapView;
    import com.google.android.gms.maps.MapsInitializer;
    import com.google.android.gms.maps.OnMapReadyCallback;
    

    【讨论】:

    • 应用程序仍然崩溃。 java.lang.NullPointerException:尝试在空对象引用上调用接口方法“void maps.ad.z.o()”
    • java.lang.NullPointerException:尝试在空对象引用上调用接口方法“void maps.ad.z.o()”
    • 仍然崩溃。
    • java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void com.google.android.gms.maps.MapView.onCreate(android.os.Bundle)”
    • 这对我来说非常有效,这可能是公认的答案!
    猜你喜欢
    • 2020-08-06
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 2015-12-12
    • 2021-10-19
    • 2011-09-03
    相关资源
    最近更新 更多