私はPlayストアで同じタブレイアウトをやろうとしています。私はandroidhiveのフラグメントとviewpagerを使って タブレイアウトを表示するようになりました。 ただし、 Google Maps v2 を実装できません。私はもう何時間もインターネットを検索しました、しかしそれをする方法についてのチュートリアルを見つけることができません。誰かに教えてください。
このコードを使用することで、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>
ここで、ファイルMapViewFragment.Java
でマップを表示するために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();
}
}
最後に、 Google Cloud Console でアプリを登録して、アプリの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
を含む最新のもの。
1。 の目録を確認してください
<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);
}
}
});
ここで私は詳細にやったこと:
代替的で簡単な方法
まずGoogleアカウントにログインしてGoogleライブラリにアクセスし 、Google Maps Android APIを選択します
android Studioのデフォルトのマップアクティビティに依存関係が見つかりました。
compile 'com.google.Android.gms:play-services:10.0.1'
下記のようなアプリケーションの下でAndroidのmainifestファイルにあなたの鍵を入れてください
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" />
NullPointerException
のTabsを変更したときにFragmentTabHost
を取得する問題については、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
の代わりに。
mapActivityを作成してそれを断片化するように膨らませるだけです。 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" />
MapFragment.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;
}
}
ビューPagerにマップフラグメントを動的に追加する:
APIレベル12より前のアプリケーションをターゲットにしている場合は、SupportedMapFragmentのインスタンスを作成し、それをビューページアダプタに追加します。
SupportMapFragment supportMapFragment=SupportMapFragment.newInstance();
supportMapFragment.getMapAsync(this);
APIレベル12以上はMapFragmentオブジェクトをサポートします
MapFragment mMapFragment=MapFragment.newInstance();
mMapFragment.getMapAsync(this);
NullPointerException
のフラグメントを削除するときのDestoryView
の回避策です。コードをonDestoryView
ではなくonStop()
に入れるだけです。それはうまくいきます!
@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 によると、nestedを使用できます。フラグメントを使用して、独自のフラグメント内のビューではなくGoogleマップフラグメントを使用する場合は、getChildFragmentManager()を呼び出してこれを実現します。
SupportMapFragment mapFragment = new SupportMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.content, mapFragment).commit();
ここで "content"はあなたのフラグメントのルートレイアウト(できればFrameLayout)です。マップフラグメントを使用する利点は、マップのライフサイクルがシステムによって自動的に管理されることです。
そのレイアウトに<fragment>が含まれていると、レイアウトをフラグメントに拡張できません。ネストされたフラグメントは、フラグメントに動的に追加された場合にのみサポートされます。大丈夫です。これが私のコードです:
フラグメントの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" />
それが役に立てば幸い!