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

Adding A GoogleMap to a Fragment Programmatically

几天来我一直在尽力解决这个问题,除了大量 Google 搜索外,我还阅读了其他 Whosebug 帖子的建议。我认为主要问题是 'getMap()' 方法已被弃用,为 'getMapAsync()' 让路,并且使用后者的解释不符合我想如何使用它。因此,考虑到这一点,我认为此时一个问题也可能与其他人相关。

基本上,到目前为止,我已经用按钮创建了一个菜单,允许用户在 Fragment 之间切换。这些 Fragments 之一需要是一个 GoogleMap,它将在按下按钮时启动,并保持按钮在视图中。

我的 MapsActivity 代码来自:-http://www.joellipman.com/articles/google/android/application-development/android-os-add-googlemap-as-fragment.html - but as mentioned, getMap() is deprecated. I also looked at -How to put Google Maps V2 on a Fragment Using ViewPager - 但问题是一样的。

MainActivity...

    public class MainActivity extends AppCompatActivity {

    Button mapMenuItem, postcodeMenuItem, nameMenuItem, recentMenuItem;
    ConnectivityManager conMgr;
    NetworkInfo networkInfo;
    FrameLayout fragmentContainer;
    NameFragment nf;
    String longiString, latiString;

    public static FragmentManager fragmentManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mapMenuItem = (Button) findViewById(R.id.mapButton);
        postcodeMenuItem = (Button) findViewById(R.id.postcodeButton);
        nameMenuItem = (Button) findViewById(R.id.nameButton);
        recentMenuItem = (Button) findViewById(R.id.recentButton);
        fragmentContainer = (FrameLayout) findViewById(R.id.fragmentContainer);

        fragmentManager = getFragmentManager();

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

}



    public void searchMap(View v) {

        android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
        android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
        MapFragment mf = new MapFragment();
        ft.replace(R.id.fragmentContainer, mf);
        ft.commit();

        mapMenuItem.setBackgroundColor(Color.parseColor("#fece35"));
        nameMenuItem.setBackgroundColor(Color.parseColor("#eff169"));
        postcodeMenuItem.setBackgroundColor(Color.parseColor("#eff169"));
        recentMenuItem.setBackgroundColor(Color.parseColor("#eff169"));

    }

MapFragment...

    public class MapFragment extends Fragment {

    MapView mapView;
    GoogleMap gMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.map_fragment, container, false);
        mapView = (MapView) v.findViewById((R.id.mapView));
        mapView.onCreate(savedInstanceState);

        mapView.onResume();

        try{
            MapsInitializer.initialize(getActivity().getApplicationContext());
        }catch (Exception e){
            e.printStackTrace();
        }

        gMap = mapView.getMap();
        double latitude = 17.385044;
        double longitude = 78.486671;

        //create marker
        MarkerOptions marker = new MarkerOptions().position(
                new LatLng(latitude, longitude)).title("Hello Maps");

        //changing marker icon
        marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));

        //adding marker
        gMap.addMarker(marker);
        CameraPosition cameraPosition = new CameraPosition.Builder().target(
                new LatLng(17.385044, 78.486671)).zoom(12).build();
        gMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));


        //Perform any camera updates
        return v;

    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }
}

MapLayout...

   <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:apiKey="@string/google_maps_key"
        android:clickable="false"/>

AcivityLayout...

</LinearLayout>

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:background="#72a972"
    android:orientation="vertical"
    android:paddingBottom="0dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    tools:context="uk.ac.mmu.webmd.foodhygieneapp.MainActivity">


    <RelativeLayout
        android:id="@+id/rel_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginTop="0dp"
        android:background="#eff169"
        android:gravity="center_horizontal">

        <Button
            android:id="@+id/mapButton"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:background="#eff169"
            android:onClick="searchMap"
            android:text="@string/MapsButton" />

        <Button
            android:id="@+id/nameButton"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toEndOf="@+id/mapButton"
            android:background="#eff169"
            android:onClick="nameMenu"
            android:text="@string/NameButton" />

        <Button
            android:id="@+id/postcodeButton"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toStartOf="@+id/recentButton"
            android:background="#eff169"
            android:onClick="postcodeMenu"
            android:text="@string/PostcodeButton" />

        <Button
            android:id="@+id/recentButton"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:background="#eff169"
            android:onClick="recentMenu"
            android:text="@string/RecentButton" />

    </RelativeLayout>

    <FrameLayout
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>


</LinearLayout>

要以编程方式加载地图,

FragmentManager fm = getSupportFragmentManager();    SupportMapFragment supportMapFragment =    SupportMapFragment.newInstance();    fm.beginTransaction().replace(R.id.mapContainer, supportMapFragment).commit();

在xml中:

<FrameLayout android:id="@+id/mapContainer" android:layout_width="match_parent" android:layout_height="match_parent"/>

创建一个 FrameLayout 作为容器以在任何布局中保存地图片段 -

<FrameLayout
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

然后以编程方式添加它 -

MapFragment mapFragment = MapFragment.newInstance();
        mapFragment.getMapAsync(this);
        getFragmentManager()
                .beginTransaction()
                .add(R.id.map, mapFragment)
                .commit();

如果在片段本身内添加地图片段,请使用 getChildFragmentManager()

如果您使用的是 SupportMapFragment 实例,请使用 getSupportFragmentManager()

How to put Google Maps V2 on a Fragment Using ViewPager

原来答案一直都在这里,抱歉浪费了大家的时间!

这是我在不使用任何布局的情况下创建地图的代码 XML。它源自许多帖子,每个帖子都贡献了图片的重要组成部分,因此感谢所有这些作者。它被设计成 运行 支持 class 所以 Activity 必须传入。结果是一个独立的 FrameLayout 里面有一个地图,所以它可以添加到任何您的应用程序中可能已有布局,允许您让地图只占据屏幕的一部分。

package pro.scanna.easycoder.android.handler;

import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;

import pro.scanna.R;

public class ProgrammaticMap {

    public void create(final AppCompatActivity activity, final ViewGroup parent) {

        FrameLayout frame = new FrameLayout(activity);
        frame.setId(R.id.reservedNamedId);
        frame.setLayoutParams(new FrameLayout.LayoutParams(
           FrameLayout.LayoutParams.MATCH_PARENT,
           FrameLayout.LayoutParams.MATCH_PARENT));
        parent.addView(frame);

        FragmentTransaction transaction =
           activity.getSupportFragmentManager().beginTransaction();
        SupportMapFragment fragment = new SupportMapFragment();
        transaction.add(frame.getId(), fragment);
        transaction.commit();

        try {
            MapsInitializer.initialize(activity);
        } catch (Exception e) {
            e.printStackTrace();
        }

        fragment.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap map) {
                setupMap(map);
            }
        });
    }

    private void setupMap(final GoogleMap map) {

        double latitude = 0;   // set this
        double longitude = 0;  // set this too
        float zoom = 17f;      // or whatever, between 2 and 21 (approx)

        map.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        map.animateCamera(CameraUpdateFactory.newLatLngZoom(
            new LatLng(latitude, longitude), zoom), 1000,
               new GoogleMap.CancelableCallback() {

            @Override
            public void onFinish() {
                doneSetup();
            }

            @Override
            public void onCancel() {
                doneSetup();
            }
        });

        map.setOnMapClickListener(new GoogleMap.OnMapClickListener()
        {
            @Override
            public void onMapClick(LatLng location)
            {
                // Here when the map is tapped
            }
        });
    }

    private void doneSetup() {
        // Do whatever comes next
    }
}

框架的 ID 需要单个资源。为此,请创建一个名为 res/values/ids.xml 的资源文件,其中包含以下内容:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="reservedNamedId" type="id"/>
</resources>