如何使用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);
- Intellij IDEA崩溃,现在抛出一个错误
- 如何在Android Studio中查看所有TODO任务?
- ActivityManager中的奇怪function:isUserAMonkey。 这是什么意思,它有什么用?
- 如何在Android中将一个Activity的值传递给另一个Activity?
- 如何在FCM通知中创build主题
- 如何将Gradle支持添加到现有项目?
- 在Android Studio中打开最后closures的标签
- 断开Android中的蓝牙套接字
- NoSuchFieldError:在Play Services 6.5中使用MapFragment时没有静态字段的MapAttrstypes