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

我试图做一个标签页布局在播放商店相同。我得显示 使用来自 androidhive 的片段和视图页面的 tab 布局。,但是,我不能实现 谷歌地图 V2在它。我已经在网上搜索了几个小时,但是我找不到关于如何做的教程。有人能告诉我怎么做吗?

264554 次浏览

通过使用这段代码,我们可以在任何地方设置 MapView,在任何 ViewPager、片段或活动中。

在最新的 GoogleforMaps 更新中,只有 MapView 支持片段。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 类设置为在文件 MapViewFragment.java中显示映射:

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();
}
}

最后,您需要通过在 谷歌云控制台注册您的应用程序来获得应用程序的 API 密钥。将你的应用注册为本地 Android 应用。

为了得到一个 NullPointerException,当我们改变 FragmentTabHost中的 Tabs 时,你只需要将这段代码添加到具有 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) {


}


}

在片段 _ 布局中

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

下面的方法对我很有用。

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();

当你添加你的地图使用:

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

而不是 .addgetFragmentManager

最新的 getMapAsync代替了已经废弃的。

1. 检查 的清单

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

您可以通过在 Google Cloud Console注册您的应用程序来获得应用程序的 API 密钥。将你的应用注册为本地 Android 应用

在你的片段布局.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);


}


}
});

我有一个解决办法为 NullPointerException时,删除片段在 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,如果你仍然想使用谷歌地图片段而不是你自己片段内的视图,你可以通过调用 GetChildFragmentManager ()来使用 嵌套的碎片来实现这一点:

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

其中“ content”是片段中的根布局(最好是 FrameLayout)。使用映射片段的优点是,这样系统就可以自动管理映射生命周期。

尽管文档中说“当一个布局包含一个 < 片段 > 时,你不能将其膨胀为片段。嵌套的片段只有在动态添加到片段时才受到支持。”,我已经成功地做到了这一点,它工作得很好。这是我的代码:
在片段的 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" />

希望能有帮助!

以下是我所做的详细介绍:

从这里你可以得到谷歌地图应用程序接口键

另类和简单的方法

首先登录到您的谷歌帐户和访问 谷歌库和选择谷歌地图 Android API

在 android 工作室默认映射活动中找到依赖项:

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" />

动态添加地图片段到视图 Pager:

如果您的目标应用程序早于 API 级别12,那么创建 SupportedMapFragment 的实例并将其添加到视图页适配器中。

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

API 级别12或更高,支持映射片段对象

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

我只是创建 MapActivity 然后把它放大成片段。 Java:

package com.example.ahmedsamra.mansouratourguideapp;


import android.support.v4.app.FragmentActivity;
import android.os.Bundle;


import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
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.MarkerOptions;


public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {


private GoogleMap mMap;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_categories);//layout for container
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new MapFragment())
.commit();
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}




/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;


// Add a marker in Sydney and move the camera
LatLng mansoura = new LatLng(31.037933, 31.381523);
mMap.addMarker(new MarkerOptions().position(mansoura).title("Marker in mansoura"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(mansoura));
}
}

Activity _ map. xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
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"
tools:context="com.example.ahmedsamra.mansouratourguideapp.MapsActivity" />

Java:-

package com.example.ahmedsamra.mansouratourguideapp;




import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


/**
* A simple {@link Fragment} subclass.
*/
public class MapFragment extends Fragment {




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




@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_maps,container,false);
return rootView;
}


}

这就是 Kotlin 的方式:

fragment_map.xml课程中,你应该:

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

在你的 MapFragment.kt课程中,你应该:

    private fun setupMap() {
(childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?)!!.getMapAsync(this)
}

调用 onCreateView中的 setupMap()