java - 如何获取对 Java 中创建的 GoogleMap 对象的引用?

标签 java android google-maps object

我正在尝试获取对由 java 创建的 GoogleMap 对象的引用,但我不知道如何获取此引用。

这是我的代码:

        LinearLayout mapLayout = new LinearLayout(customToursActivity);
        mapLayout.setId(generateViewId(rootView));
        int mapLayoutHeight = Math.round(getResources().getDimension(R.dimen.custom_tour_list_map_size));
        mapLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, mapLayoutHeight));
        layout.addView(mapLayout);

        FragmentManager fm = getChildFragmentManager();
        SupportMapFragment supportMapFragment =  SupportMapFragment.newInstance();
        fm.beginTransaction().replace(mapLayout.getId(), supportMapFragment).commit();
        GoogleMap mMap = supportMapFragment.getMap();
        mMap.setMyLocationEnabled(true);

这是我得到的日志:

01-23 17:09:54.168    3795-3795/abff.googlemapsappteste E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: abff.googlemapsappteste, PID: 3795
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(boolean)' on a null object reference
            at abff.googlemapsappteste.CustomToursList.createPlacemarksList(CustomToursList.java:458)
            at abff.googlemapsappteste.CustomToursList.onCreateView(CustomToursList.java:73)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
            at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
            at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:1105)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:951)
            at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1473)
            at android.view.View.measure(View.java:17637)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
            at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
            at android.view.View.measure(View.java:17637)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
            at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:444)
            at android.view.View.measure(View.java:17637)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
            at android.view.View.measure(View.java:17637)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
            at android.view.View.measure(View.java:17637)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2618)
            at android.view.View.measure(View.java:17637)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2019)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1177)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1383)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1065)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5901)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
            at android.view.Choreographer.doCallbacks(Choreographer.java:580)
            at android.view.Choreographer.doFrame(Choreographer.java:550)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:211)
            at android.app.ActivityThread.main(ActivityThread.java:5389)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)

最佳答案

有几种方法可以做到这一点。

1)。如果您的目标应用程序是 API 级别 12 之后的应用程序,那么您只需使用 MapFragment 而不是 SupportMapFragment。以下是如何将 MapFragment 添加到 Fragment 并获取对 GoogleMap 对象的引用的示例代码。

 Map mapFragment = MapFragment.newInstance();
 FragmentTransaction fragmentTransaction =
         getChildFragmentManager().beginTransaction();
 fragmentTransaction.replace(mapLayout.getId(), mapFragment).commit();

然后使用 getMapAsync() 在 fragment 上设置回调。

mapFragment.getMapAsync(this); // your fragment need to implement `OnMapReadyCallback`

Note: getMapAsync() must be called from the main thread, and the callback will be executed in the main thread. If Google Play services is not installed on the user's device, the callback will not be triggered until the user installs Play services.

使用 onMapReady(GoogleMap) 回调方法获取 GoogleMap 对象的句柄。本地图可供使用时会触发回调。它提供了一个非空的 GoogleMap 实例。例如,您可以使用 GoogleMap 对象设置 map 的 View 选项或添加标记。

    @Override
public void onMapReady(GoogleMap map) {
      map.setMyLocationEnabled(true);
}

可以引用官方文档here

2)。但是,如果您的目标应用程序早于 API 级别 12,或者出于某种原因您仍想使用 SupportMapFragment,则还可以有两个选项。

a). 由于 map 初始化是异步的,因此您必须等待 SupportMapFragment.onCreateView() 被调用,这基本上是在 Fragment onActivityCreated 之后调用()onStart() 之前。因此,如果您将 SupportMapFragment 添加到 onActivityCreated() 内的事务中,那么您将在 onStart() 中返回 getMap() 对象code> 或 onResume() (当然,除非 Google Play 服务不可用)。下面是代码示例。

public class MyFragment extends Fragment {

    private SupportMapFragment mSupportMapFragment;
    private GoogleMap mGoogleMap;

    @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();
        mSupportMapFragment =  SupportMapFragment.newInstance();
        fm.beginTransaction().replace(mapLayout.getId(),mSupportMapFragment).commit();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mGoogleMap == null) {
            mGoogleMap = mSupportMapFragment.getMap();
        }
    }
}

如果您遇到任何 IllegalStateException(Google Bug 中跟踪的问题),只需覆盖您的 Fragment onDetach()

@Override
public void onDetach() {
    super.onDetach();
    try {
        Field childFragmentManager = Fragment.class
                .getDeclaredField("mChildFragmentManager");
        childFragmentManager.setAccessible(true);
        childFragmentManager.set(this, null);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

b)。您可以重写 SupportMapFragmentonActivityCreated()。例如。

public class MyFragment extends Fragment {

        private SupportMapFragment mSupportMapFragment;
        private GoogleMap mGoogleMap;

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.layout_with_map, container, false);
    mSupportMapFragment = new SupportMapFragment() {
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            mGoogleMap = mSupportMapFragment.getMap();
            if (mGoogleMap != null) {
               mGoogleMap.setMyLocationEnabled(true);
            }
        }
    };
    getChildFragmentManager().beginTransaction().replace(mapLayout.getId(), mSupportMapFragment).commit();;
    return view;   
   }
}

关于java - 如何获取对 Java 中创建的 GoogleMap 对象的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34966462/

相关文章:

android - 在使用 CursorAdapter 的情况下如何更新 ListView?

Android : Getting a Bitmap from a url connection (graph. facebook.com)重定向到另一个网址

javascript - 谷歌地图国家缩放级别

javascript - 谷歌地图 react : Open InfoWindow by Default - not from onClick

google-maps - Google Map成为Illustrator SVG

java - 在 spring + angular 中获取当前登录的用户

android - Retrofit 从基本 url 中删除查询参数

java - 如何过滤 HTTP get 响应?

java - 从 .txt 文件中删除特殊字符会在 Java 中给出 `LRB` 、 `LSB` 、 `RSB` 、 `LRB` 、 `RRB` 等

java - 图像按钮点击更改图像