I have fragment for map in XML file as below,
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" >
</fragment>
In which activity I am displaying the Google map, that is not a main activity. I am redirecting to map activity from my main activity on button click. There is no any problem with map. But when I click on button of main activity then the process stops for sometime and suddenly black screen arrives in front and after sometime, map activity displays the map. It is not expected behaviour of application. Is there any way to load that map after map activity loaded? I mean loading map in background?
Use getMapAsync() (introduced in Google Play Services v6.5.87) instead of getMap() then Implement OnMapReadyCallback on your fragment:
#Override
public void onMapReady(GoogleMap map) {
// do something with map
}
Related
I have recently started using here maps api, and i have encountered some difficulties implementing maps. When app goes in background and i come back to app, map view screen is black. I should mention that i'm using MapView and not MapFragment. MapView is inside fragment view. Beside that map is showing clearly.
mapView.setMap(mMap);
mMap = mapView.getMap();
mMap.setZoomLevel(16);
mapMarker = new MapMarker();
mapMarker.setTitle("Neki naslov");
mapMarker.setDescription("Neki opis");
mapMarker.setDraggable(true);
mapView.setMapMarkerDragListener(mOnDragListener);
mapMarker.setCoordinate(PositioningManager.getInstance().getLastKnownPosition().getCoordinate());
mMap.addMapObject(mapMarker);
mapMarker.showInfoBubble();
mMap.setCenter(PositioningManager.getInstance().getLastKnownPosition().getCoordinate(),
Map.Animation.NONE);
Most likely, you did not call MapView#onResume() and MapView#onPause() as part of the activity / fragment life cycle. If it is not called, the underlying rendering thread will not be resumed.
#Dusan, your code does not have an image for the marker, so there is no marker to show.
Hello I am using a support map fragment for my Android map. Other than using default settings (no customisation), i noticed out of the box that the map seems to provide location updates automatically i.e. a dot on the map which tells where the user is and periodically updates.
My map fragment is apart of a layout whereby the map fragment visibility can be set to GONE and some other content is shown in its place.
My question is, how do i programmatically stop these location updates? I noticed when the activity which hosts the map fragment goes in a stop state, the location updates stop.
This is the behaviour i want to mimic but for when the visibility of the fragment changes.
In XML
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
Initialised in code
SupportMapFragment mapFragment = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map));
mapFragment.getMapAsync(this);
Some settings set in onMapReady callback
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mGoogleMap.getUiSettings().setZoomControlsEnabled(false);
mGoogleMap.setOnMyLocationButtonClickListener(this);
mGoogleMap.setOnMarkerClickListener(this);
Try this code
mGoogleMap.setMyLocationEnabled(false);
As far as I can see, MapFragment has an issue with transition animations. All views on the layout are getting shown immediately, including the MapFragment's own views (like zoom buttons). But the map itself gets loaded with a lag only after the animation is completed.
In order to illustrate the problem, I did the following:
I changed one of the Activities in the Google maps android API examples slightly. It opens a blank activity via an Action Item. When I click back button, the map gets loaded, but only after the transition is completed.
I exaggerated the transition effect a little bit, so that you can see the problem better. I set the transition animation speed in Developer Options to 5x. Even on 1x speed, this lag is disturbing though.
See this video: http://www.youtube.com/watch?v=12SEotktlXI
Do you have any suggestion to prevent this lag? Why do all views get loaded immediately but the map itself doesn't?
Testing environment: Nexus 5, Android 4.4.2, unrooted
Edit: This problem also occures when MapView is used instead of MapFragment.
Reason: Its because as soon as you settings activity will be shown, the map activity will be on its onpause() state; thus, I assume android management reclaimed the memory from the map activity.
Solution:
Make a static class and declare you map statically there, to avoid android from reclaiming the memory used by your map.
Ex.
//your static class
public class MapData{
public static GoogleMap map;
}
//your map activity
public class MapActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(MapData.map != null)
MapData.map = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
}
}
EDIT
I've found a better STR:
Make sure to set "Do not keep activities" in Developer options in Settings.
Open the app with a SupportMapFragment as a child fragment of another fragment.
Switch to another app
Open your app again
Notice you can't interact with the map and no animations work.
Open another screen within the app
Notice there's a single frame or so of the map with the markers drawn on screen.
I have an issue with Google Maps API v2.
I am animating the camera to zoom to a set of custom marker bitmaps rendered on a MapFragment.
On selecting one of these marker tooltips I open a geo: intent (for the Google Maps app etc.)
When the user presses back it reopens my activity with the fragment back stack rebuilt.
My issue is that it doesn't render camera animations or the markers on coming back, though there is a brief display of those markers when the user presses back to go to the previous fragment.
The GoogleMap instance has the markers, but it doesn't render them - I'm guessing because the MapFragment/MapView thinks it doesn't need to be rendered.
How do I force a render of the MapView? Failing that, how do I get the MapView to recognise that the model has changed?
The issue was to do with the way I was handling my child fragments.
Every time the parent fragment would call onCreate the children fragments would get recreated.
I did the following to handle my child fragments, but there may be a better way:
private static final String TAG_FRAGMENT_MAP = "TagFragmentMap";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
if (savedInstanceState == null) {
// create the fragments for the first time
ft.add(R.id.view_flip, new SupportMapFragment(), TAG_FRAGMENT_MAP);
ft.commit();
}
}
// ...
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
mMapFragment = (SupportMapFragment)findFragmentByTag(TAG_FRAGMENT_MAP);
}
I have an app which contains an activity which is a MapviewActivity and is mostly a mapview.
However I have noticed that the start up time of the activity is really slow and causes a lag from the moment the button is pressed to go in to the map activity. I feel this creates a bad user experience and would like to avoid this.
I have already set the background of the map activity to #null as suggested by one of the UI improvement articles on googles developer page, which I feel does not do the trick.
Is there a way to improve this? I would not like the main home screen to get stuck on the launch of the activity, even a transfer to the map activity and then loading the mapview would be better.
Thanks,
Jason
You could try removing the MapView from your layout. Then, in onCreate(), use post() to schedule a Runnable to add in the MapView and do your map-related initialization from Java. By using post() (or, potentially, postDelayed()) to postpone the MapView further, you should be able to render the rest of the activity first.
I haven't tried this, so YMMV. :-)
This has been bugging me for a while and I worked this out by expanding on on CommonsWare's answer:
I am currently using this solution that sped up my Activity loading time greatly and make everything look as smooth as it gets.
My MapActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map); // See activity_map.xml below.
// Start a runnable that does the entire Map setup.
// A delay does not seem to be necessary.
Handler mapSetupHandler = new Handler();
Runnable mapSetupRunnable = new Runnable() {
public void run() {
FragmentManager fragMan = getSupportFragmentManager();
FragmentTransaction fragTransaction = fragMan.beginTransaction();
final SupportMapFragment mapFragment = new SupportMapFragment();
fragTransaction.add(R.id.container_map, mapFragment, "mapFragment");
fragTransaction.commit();
// At the end, retrieve the GoogleMap object and the View for further setup,
// zoom in on a region, add markers etc.
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMapView = mapFragment.getView();
setUpMap();
}
});
}
};
mapSetupHandler.post(mapSetupRunnable);
}
layout/activity_map.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--This FrameLayout will be used by the GoogleMap-->
<!--as a container for the SupportMapFragment.-->
<FrameLayout
android:id="#+id/container_map"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_above="#id/bar_room_password"
android:layout_below="#id/toolbar">
<!--Initially the container is filled with a placeholder image.-->
<!--A small, heavily blurred image of a map screenshot is used-->
<!--in order to fake a loading map.-->
<ImageView
android:id="#+id/image_map_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="50"
android:contentDescription="#string/map"
android:scaleType="centerCrop"
android:src="#drawable/placeholder_map" />
</FrameLayout>
[... more, unrelated Views...]
</RelativeLayout>
The Activity appears quickly because the setup is handled inside of a Runnable. Also, instead of just showing an empty View while the GoogleMap is doing its setup and downloads, I show a vague fake image of a map.
The Google logo is being placed on top of the ImageView relatively early so it looks pretty convincing with just a 128x128 pixel image:
I tried CommonsWare's answer, but there was a significantly delay launching even a bare MapActivity without a MapView in it.
So, I put another activity in the middle, "MapLoading". My home activity launches MapLoading, which then uses post() to immediately launch the MapActivity. Because of the lag, the app sticks on MapLoading for a few seconds (which is the intended result, as opposed to sticking on my home activity).
The MapLoading activity has noHistory set so when the back button is clicked from the MapActivity it goes right through to the home screen. Future launches of the MapActivity are very fast and the MapLoading activity just flashes on the screen.
Here is the code for MapLoading (the activity with the MapView in it is called Map):
public class MapLoading extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.maploading);
new Handler().post(new Runnable() {
public void run()
{
startActivity(new Intent(MapLoading.this, Map.class));
}
});
}
}
Here is its layout:
<?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" >
<TextView
android:id="#+id/maploading"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:textSize="14pt"
android:text="Loading map..."
/>
</RelativeLayout>
And the corresponding stanza in AndroidManifest.xml:
<activity android:label="#string/app_name"
android:name="MapLoading"
android:noHistory="true" />