如何使用ViewPager将Google Maps V2放在片段上

我正在尝试在Play商店中制作相同的标签页布局。 我必须使用来自androidhive的片段和viewpager来显示标签布局。 不过,我无法在其上实施Google地图v2 。 我已经在互联网上search了几个小时了,但是我找不到关于如何操作的教程。 有人可以告诉我怎么样。 谢谢!

通过使用这个代码,我们可以在任何ViewPager或Fragment或Activity中的任何地方设置MapView。

在Google for Maps的最新更新中,只有MapView支持片段。 MapFragment&SupportMapFragment不起作用。 我可能是错的,但是这是我尝试实现MapFragment&SupportMapFragment后看到的。

设置显示地图的布局。 location_fragment.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.google.android.gms.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> 

现在我们编写Java类来显示Map。 MapViewFragment

 public class MapViewFragment extends Fragment { MapView mMapView; private GoogleMap googleMap; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.location_fragment, container, false); mMapView = (MapView) rootView.findViewById(R.id.mapView); mMapView.onCreate(savedInstanceState); mMapView.onResume(); // needed to get the map to display immediately try { MapsInitializer.initialize(getActivity().getApplicationContext()); } catch (Exception e) { e.printStackTrace(); } mMapView.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap mMap) { googleMap = mMap; // For showing a move to my location button googleMap.setMyLocationEnabled(true); // For dropping a marker at a point on the Map LatLng sydney = new LatLng(-34, 151); googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker Title").snippet("Marker Description")); // For zooming automatically to the location of the marker CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build(); googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } }); return rootView; } @Override public void onResume() { super.onResume(); mMapView.onResume(); } @Override public void onPause() { super.onPause(); mMapView.onPause(); } @Override public void onDestroy() { super.onDestroy(); mMapView.onDestroy(); } @Override public void onLowMemory() { super.onLowMemory(); mMapView.onLowMemory(); } } 

最后,您需要通过在Google云端控制台注册您的应用来获取您的应用的API密钥。 将您的应用注册为原生Android应用。

以下方法适用于我。

 import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.google.android.gms.maps.CameraUpdateFactory; 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.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; /** * A fragment that launches other parts of the demo application. */ public class MapFragment extends Fragment { MapView mMapView; private GoogleMap googleMap; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // inflat and return the layout View v = inflater.inflate(R.layout.fragment_location_info, container, false); mMapView = (MapView) v.findViewById(R.id.mapView); mMapView.onCreate(savedInstanceState); mMapView.onResume();// needed to get the map to display immediately try { MapsInitializer.initialize(getActivity().getApplicationContext()); } catch (Exception e) { e.printStackTrace(); } googleMap = mMapView.getMap(); // latitude and longitude 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 googleMap.addMarker(marker); CameraPosition cameraPosition = new CameraPosition.Builder() .target(new LatLng(17.385044, 78.486671)).zoom(12).build(); googleMap.animateCamera(CameraUpdateFactory .newCameraPosition(cameraPosition)); // Perform any camera updates here return v; } @Override public void onResume() { super.onResume(); mMapView.onResume(); } @Override public void onPause() { super.onPause(); mMapView.onPause(); } @Override public void onDestroy() { super.onDestroy(); mMapView.onDestroy(); } @Override public void onLowMemory() { super.onLowMemory(); mMapView.onLowMemory(); } } 

fragment_location_info.xml

 <?xml version="1.0" encoding="utf-8"?> <com.google.android.gms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" /> 

如果你想在片段中使用GoogleMap ,你可以使用这一行:

 <fragment android:id="@+id/map" android:layout_width="wrap_content" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment" /> 
 GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap(); 

最新的东西与getMapAsync而不是弃用的。

检查清单

 <meta-data android:name="com.google.android.geo.API_KEY" android:value="xxxxxxxxxxxxxxxxxxxxxxxxx"/> 

您可以在Google Cloud Console注册您的应用,从而获取应用的API密钥。 将您的应用注册为原生Android应用

2.在你的片段布局中.xml添加FrameLayout(不是片段):

  <FrameLayout android:layout_width="match_parent" android:layout_height="250dp" android:layout_weight="2" android:name="com.google.android.gms.maps.SupportMapFragment" android:id="@+id/mapwhere" /> 

或任何你想要的高度

3.在你的片段中的onCreateView

  private SupportMapFragment mSupportMapFragment; mSupportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapwhere); if (mSupportMapFragment == null) { FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); mSupportMapFragment = SupportMapFragment.newInstance(); fragmentTransaction.replace(R.id.mapwhere, mSupportMapFragment).commit(); } if (mSupportMapFragment != null) { mSupportMapFragment.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googleMap) { if (googleMap != null) { googleMap.getUiSettings().setAllGesturesEnabled(true); -> marker_latlng // MAKE THIS WHATEVER YOU WANT CameraPosition cameraPosition = new CameraPosition.Builder().target(marker_latlng).zoom(15.0f).build(); CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); googleMap.moveCamera(cameraUpdate); } } }); 

对于在FragmentTabHost更改Tabs时发生NullPointerException的问题,您只需将此代码添加到具有TabHost类中即可。 我的意思是你初始化标签的类。 这是代码:

 /**** Fix for error : Activity has been destroyed, when using Nested tabs * We are actually detaching this tab fragment from the `ChildFragmentManager` * so that when this inner tab is viewed back then the fragment is attached again****/ import java.lang.reflect.Field; @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); } } 
 public class DemoFragment extends Fragment { MapView mapView; GoogleMap map; LatLng CENTER = null; public LocationManager locationManager; double longitudeDouble; double latitudeDouble; String snippet; String title; Location location; String myAddress; String LocationId; String CityName; String imageURL; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater .inflate(R.layout.fragment_layout, container, false); mapView = (MapView) view.findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); setMapView(); } private void setMapView() { try { MapsInitializer.initialize(getActivity()); switch (GooglePlayServicesUtil .isGooglePlayServicesAvailable(getActivity())) { case ConnectionResult.SUCCESS: // Toast.makeText(getActivity(), "SUCCESS", Toast.LENGTH_SHORT) // .show(); // Gets to GoogleMap from the MapView and does initialization // stuff if (mapView != null) { locationManager = ((LocationManager) getActivity() .getSystemService(Context.LOCATION_SERVICE)); Boolean localBoolean = Boolean.valueOf(locationManager .isProviderEnabled("network")); if (localBoolean.booleanValue()) { CENTER = new LatLng(latitude, longitude); } else { } map = mapView.getMap(); if (map == null) { Log.d("", "Map Fragment Not Found or no Map in it!!"); } map.clear(); try { map.addMarker(new MarkerOptions().position(CENTER) .title(CityName).snippet("")); } catch (Exception e) { e.printStackTrace(); } map.setIndoorEnabled(true); map.setMyLocationEnabled(true); map.moveCamera(CameraUpdateFactory.zoomTo(5)); if (CENTER != null) { map.animateCamera( CameraUpdateFactory.newLatLng(CENTER), 1750, null); } // add circle CircleOptions circle = new CircleOptions(); circle.center(CENTER).fillColor(Color.BLUE).radius(10); map.addCircle(circle); map.setMapType(GoogleMap.MAP_TYPE_NORMAL); } break; case ConnectionResult.SERVICE_MISSING: break; case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: break; default: } } catch (Exception e) { } } 

在fragment_layout中

 <com.google.android.gms.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="160dp" android:layout_marginRight="10dp" /> 

当你添加你的地图使用:

 getChildFragmentManager().beginTransaction() .replace(R.id.menu_map_container, mapFragment, "f" + shabbatIndex).commit(); 

而不是.add而不是getFragmentManager

在这里我详细地做了:

从这里你可以得到谷歌地图API密钥

另类和简单的方法

首先login到您的谷歌帐户,并访问谷歌图书馆,并select谷歌地图Android API

在android studio默认地图活动中发现的依赖:

 compile 'com.google.android.gms:play-services:10.0.1' 

把你的密钥放到Android应用程序的下面

在AndroidMainifest.xml中进行这些更改:

  // required permission <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> // google map api key put under/inside <application></application> // android:value="YOUR API KEY" <meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzasdfasdf645asd4f847sad5f45asdf7845" /> 

片段代码:

 public class MainBranchFragment extends Fragment implements OnMapReadyCallback{ private GoogleMap mMap; public MainBranchFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view= inflater.inflate(R.layout.fragment_main_branch, container, false); SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.main_branch_map); mapFragment.getMapAsync(this); return view; } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; LatLng UCA = new LatLng(-34, 151); mMap.addMarker(new MarkerOptions().position(UCA).title("YOUR TITLE")).showInfoWindow(); mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(UCA,17)); } } 

在你的片段xml中:

 <fragment android:id="@+id/main_branch_map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.googlemap.googlemap.MapsActivity" /> 

我有一个解决schemeNullPointerException当在DestoryView删除片段,只要把你的代码在onStop()不是onDestoryView 。 它工作正常!

 @Override public void onStop() { super.onStop(); if (mMap != null) { MainActivity.fragmentManager.beginTransaction() .remove(MainActivity.fragmentManager.findFragmentById(R.id.location_map)).commit(); mMap = null; } } 

根据https://developer.android.com/about/versions/android-4.2.html#NestedFragments ,如果您仍然想使用Google Maps片段而不是使用嵌套片段来调用getChildFragmentManager()在你自己的片段里面查看:

 SupportMapFragment mapFragment = new SupportMapFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.content, mapFragment).commit(); 

其中“内容”是你的片段的根布局(最好是一个FrameLayout)。 使用地图片段的优点是,地图生命周期由系统自动pipe理。

尽pipe文档中提到:“当布局包含一个<fragment>时,不能将布局膨胀成一个片段,只有在dynamic添加到一个片段时才支持嵌套片段。”,我不知何故成功地完成了这个工作,并且工作正常。 这是我的代码:
在片段的onCreateView()方法中:

 View view = inflater.inflate(R.layout.layout_maps, container, false); SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(...); 

在布局中:

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

希望能帮助到你!

dynamic添加地图片段查看寻呼机:

如果您的应用程序早于API级别12,请创buildSupportedMapFragment实例并将其添加到您的视图页面适配器。

 SupportMapFragment supportMapFragment=SupportMapFragment.newInstance(); supportMapFragment.getMapAsync(this); 

API级别12或更高版本支持MapFragment对象

 MapFragment mMapFragment=MapFragment.newInstance(); mMapFragment.getMapAsync(this);