可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a fragment which is a part of Viewpager, and I want to use Google Map V2 inside that fragment. This is what I have tried so far,
In my fragment,
private SupportMapFragment map;
private GoogleMap mMapView;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
map = (SupportMapFragment) fm.findFragmentById(R.id.map);
if (map == null) {
map = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map, map).commit();
}
}
@Override
public void onResume() {
super.onResume();
if (mMapView == null) {
mMapView = map.getMap();
Marker hamburg = mMapView.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
Marker kiel = mMapView.addMarker(new MarkerOptions()
.position(KIEL)
.title("Kiel")
.snippet("Kiel is cool")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_launcher)));
mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
// Zoom in, animating the camera.
mMapView.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
}
}
and in my layout subfragment_info.xml , I have,
<fragment
android:id="@+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:layout_below="@+id/tableLayout1" />
I can see the map now. But the markers are not showing. I think my Google map mMapView is null. Please help me to get this problem solved. Thanks in advance.
回答1:
Create a frame for map in which it will be added in your xml layout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map_container">
<!-- The map fragments will go here -->
</RelativeLayout>
Don't include class="com.google.android.gms.maps.SupportMapFragment" in xml
either in your fragment class do get it manually inside onActivityCreated
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment).commit();
}
/***at this time google play services are not initialize so get map and add what ever you want to it in onResume() or onStart() **/
}
@Override
public void onResume() {
super.onResume();
if (map == null) {
map = fragment.getMap();
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)));
}
}
if you guys face any problem Illegal State Exception Occur just write below code
/*
* This issue Is tracked in (Google Bugs)
* http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064 Added
* Code Due to Illegal State Exception Occur when reclicking on tab
*
* A short-term workaround that fixed it for me is to add the following to
* onDetach() of every Fragment which you call
*/
@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);
}
}
//If you want to show map in activity just extend your Activity by //FragmentActivity write code mention below
In onCreate
FragmentManager fm = getSupportFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment)
.commit();
}
In onResume
@Override
protected void onResume() {
super.onResume();
if (googleMap == null) {
initilizeMap();
}
}
private void initilizeMap() {
if (googleMap != null) {
googleMap = fragment.getMap();
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(true);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(latitude, longitude)).zoom(10).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
// create marker
MarkerOptions marker = new MarkerOptions().position(new LatLng(
latitude, longitude));
// ROSE color icon
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
googleMap.addMarker(marker);
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
}
Additional help can get from these links
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1
https://developers.google.com/maps/documentation/android/map
回答2:
You have to decide if you create your fragment in code new SupportMapFragment()
or inflate from xml class="com.google.android.gms.maps.SupportMapFragment"
.
Actually you cannot have a Fragment
in xml for another Fragment
. Read about nested Fragment
s.
You may follow this comment on how to add nested SupportMapFragment
.
回答3:
I had more or less the same problem. I had a Navigation Drawer and I wanted to put the map in a fragment.
I followed this thread (but it is in Spanish):
https://groups.google.com/forum/#!msg/desarrolladores-android/1cvqPm0EZZU/Q801Yvb2ntYJ
The clue was (in my opinion) to change the layout.xml file:
Instead of a "fragment" inside your "layout subfragment_info.xml" you would need to change to this:
<com.google.android.gms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />`
Here it is the code inside the thread (you could use it and adapt):
https://groups.google.com/d/msg/desarrolladores-android/1cvqPm0EZZU/9srw_9feamUJ
回答4:
my approach is:
Bundle bundle = new Bundle();
bundle.putInt(MY_ID, id);
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.customer_details_fragment);
fragment = new SalesFragment();
fm.beginTransaction()
.add(R.id.customer_details_fragment, fragment)
.commit();
fragment.setArguments(bundle);
回答5:
For MapFragment
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
In your Fragment Class
map = ((MapFragment) getActivity().getFragmentManager()
.findFragmentById(R.id.map)).getMap();
map.addMarker(new MarkerOptions().position(
new LatLng(13.031902, 80.278823)).title("Marker Title"));
For SupportMapFragment
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
In your Fragment Class
map = ((SupportMapFragment) getActivity().getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
map.addMarker(new MarkerOptions().position(
new LatLng(13.031902, 80.278823)).title("Marker Title"));
Note - SupportMapFragment map render once user touchs the map
回答6:
In link , answer for you:
"The problem is that what you are trying to do shouldn't be done. You shouldn't be inflating fragments inside other fragments. From Android's documentation:
Note: You cannot inflate a layout into a fragment when that layout includes a . Nested fragments are only supported when added to a fragment dynamically.
While you may be able to accomplish the task with the hacks presented here, I highly suggest you don't do it. Its impossible to be sure that these hacks will handle what each new Android OS does when you try to inflate a layout for a fragment containing another fragment.
The only Android-supported way to add a fragment to another fragment is via a transaction from the child fragment manager."
For this problem:
Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment
For me, the best solution are of @DeepakPanwar
回答7:
For Load map into fragment:
<fragment
android:id="@+id/fragmentMap1"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
For .java:
public class PathFragment extends Fragment {
View view;
GoogleMap mMap;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_path,null);
setupMap();
return view;
}
private void setupMap()
{
if (mMap == null)
{
mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_map1)).getMap();
mMap.getUiSettings().setZoomControlsEnabled(true);
}
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
getlocation();
}
});
}
public void getlocation()
{
try
{
/*Collect Source and destination latitude and longitude
* To draw Polyline
* */
LatLng src = new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lng()));
LatLng dest =new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lng()));
//Add Marker
mMap.addMarker(new MarkerOptions()
.position(src)
.title("Source")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.srcicon)));
mMap.addMarker(new MarkerOptions()
.position(dest)
.title("Destination")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.desticon)));
Polyline line = mMap.addPolyline(
new PolylineOptions().add(
new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude)
).width(5).color(Color.RED).geodesic(true)
);
//set zoom level
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(src);
builder.include(dest);
LatLngBounds bounds = builder.build();
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
mMap.animateCamera(cu);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
回答8:
This is how I did it
in layout:
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight=".90"
class="com.google.android.gms.maps.SupportMapFragment"
/>
in code:
public class GPS extends FragmentActivity {
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (supportMap == null) {
// Try to obtain the map from the SupportMapFragment.
supportMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (supportMap != null) {
MarkerOptions mo = new MarkerOptions().position( new LatLng( latitude, longitude ) );
supportMap.addMarker( mo );
}
}
}
}
Took me a lot of fiddling, you need just the right combination of things, make sure your class extends FragmentActivity
回答9:
If I replace the fragment, where the map fragment is in (in this code example MyFragment) with a different fragment and then come back, I get an IllegalStateException
public class Home_Map extends Fragment {
GoogleMap googleMap;
FragmentManager myFragmentManager;
SupportMapFragment mySupportMapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View rootView = inflater.inflate(R.layout.fragment_home__map, container, false);
//googleMap.setMyLocationEnabled(true);
try {
// Loading map
initilizeMap();
googleMap.setMyLocationEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
return rootView;
}
private void initilizeMap() {
try
{
if (googleMap == null) {
myFragmentManager = getFragmentManager();
mySupportMapFragment = (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map2);
googleMap = mySupportMapFragment.getMap();
if (googleMap == null) {
Toast.makeText(getActivity().getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
} catch (Exception e) { Toast.makeText(getActivity().getApplicationContext(), ""+e, 1).show();
// TODO: handle exception
}
}
@Override
public void onResume() {
super.onResume();
initilizeMap();
}
@Override
public void onDetach() {
// TODO Auto-generated method stub
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);
}
}
}