Ich versuche, im Play Store ein Tab-Layout zu erstellen. Ich konnte das Tab-Layout mit einem Fragmenten und Viewpager von AndroidHive anzeigen. Ich kann jedoch nicht google maps v2 darauf implementieren. Ich habe bereits stundenlang im Internet gesucht, finde aber keine Anleitung, wie das geht. Kann mir jemand bitte zeigen wie?
Mit diesem Code können Sie MapView überall in einem ViewPager, Fragment oder einer Aktivität einrichten.
Im neuesten Update von Google für Maps wird nur MapView für Fragmente unterstützt. MapFragment & SupportMapFragment funktioniert nicht. Ich bin falsch, aber ich habe das gesehen, als ich MapFragment & SupportMapFragment implementiert habe.
Einrichten des Layouts für die Anzeige der Karte in der Datei 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>
Jetzt codieren wir die Java-Klasse, um die Karte in der Datei MapViewFragment.Java
anzuzeigen:
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();
}
}
Schließlich benötigen Sie den API-Schlüssel für Ihre App, indem Sie Ihre App bei Google Cloud Console registrieren. Registrieren Sie Ihre App als native Android-App.
Der folgende Ansatz funktioniert für mich.
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" />
Sie können diese Zeile verwenden, wenn Sie GoogleMap
in einem Fragment verwenden möchten:
<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();
Neueste Informationen mit getMapAsync
anstelle des veralteten.
1. Manifest prüfen für
<meta-data Android:name="com.google.Android.geo.API_KEY" Android:value="xxxxxxxxxxxxxxxxxxxxxxxxx"/>
Sie können den API-Schlüssel für Ihre App abrufen, indem Sie Ihre App unter Google Cloud Console
registrieren. Registrieren Sie Ihre App als native Android-App
2. Fügen Sie in Ihrem Fragment-Layout .xml FrameLayout hinzu (nicht Fragment):
<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" />
oder welche Höhe Sie wünschen
3. In onCreateView in deinem Fragment
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);
}
}
});
hier was ich im detail gemacht habe:
Von hier aus können Sie Google Map-API-Schlüssel erhalten
alternativer und einfacher Weg
melden Sie sich zuerst bei Ihrem Google-Konto an und besuchen Sie die Google-Bibliotheken, und wählen Sie Google Maps Android API aus.
abhängigkeit in der Android-Studio-Standardkartenaktivität gefunden:
compile 'com.google.Android.gms:play-services:10.0.1'
legen Sie Ihren Schlüssel in die Android-Hauptakte-Datei unter Anwendung wie unten
nehmen Sie in AndroidMainifest.xml diese Änderungen vor:
// 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" />
Fragmentcode:
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));
}
}
in dir fragment 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" />
Für das Problem, eine NullPointerException
zu erhalten, wenn wir die Registerkarten in einer FragmentTabHost
ändern, müssen Sie nur diesen Code Ihrer Klasse hinzufügen, die die TabHost
hat. Ich meine die Klasse, in der Sie die Registerkarten initialisieren. Dies ist der Code:
/**** 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) {
}
}
in 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" />
Wenn Sie Ihre Karte hinzufügen, verwenden Sie:
getChildFragmentManager().beginTransaction()
.replace(R.id.menu_map_container, mapFragment, "f" + shabbatIndex).commit();
anstelle von .add
und anstelle von getFragmentManager
.
ich erstelle einfach MapActivity und blase es auf, um es zu fragmentieren. 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;
}
}
Kartenfragment dynamisch zum Anzeigen von Pager hinzufügen:
Wenn Sie sich auf eine Anwendung vor API 12 beziehen, erstellen Sie eine Instanz von SupportedMapFragment und fügen Sie sie Ihrem Ansichtseitenadapter hinzu.
SupportMapFragment supportMapFragment=SupportMapFragment.newInstance();
supportMapFragment.getMapAsync(this);
API-Ebene 12 oder höher unterstützt MapFragment-Objekte
MapFragment mMapFragment=MapFragment.newInstance();
mMapFragment.getMapAsync(this);
Ich habe eine Problemumgehung für NullPointerException
, wenn Sie das Fragment in DestoryView
entfernen. Fügen Sie einfach Ihren Code in onStop()
nicht onDestoryView
ein. Es funktioniert gut!
@Override
public void onStop() {
super.onStop();
if (mMap != null) {
MainActivity.fragmentManager.beginTransaction()
.remove(MainActivity.fragmentManager.findFragmentById(R.id.location_map)).commit();
mMap = null;
}
}
Gemäß https://developer.Android.com/about/versions/Android-4.2.html#NestedFragments können Sie geschachtelte Fragmente verwenden, indem Sie getChildFragmentManager () aufrufen., wenn Sie weiterhin das Google Maps-Fragment anstelle der Ansicht in Ihrem eigenen Fragment verwenden möchten:
SupportMapFragment mapFragment = new SupportMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.content, mapFragment).commit();
dabei ist "Inhalt" das Stammlayout in Ihrem Fragment (vorzugsweise ein FrameLayout). Die Verwendung eines Kartenfragments hat den Vorteil, dass der Kartenlebenszyklus automatisch vom System verwaltet wird.
In der Dokumentation heißt es zwar "Sie können ein Layout nicht in ein Fragment aufpumpen, wenn dieses Layout ein <fragment> enthält. Verschachtelte Fragmente werden nur unterstützt, wenn sie dynamisch zu einem Fragment hinzugefügt werden", ich habe dies irgendwie erfolgreich gemacht und es hat gut funktioniert. Hier ist mein Code:
In der onCreateView () - Methode des Fragments:
View view = inflater.inflate(R.layout.layout_maps, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(...);
Im Layout:
<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" />
Ich hoffe es hilft!