You might know that the android studio offers a project skeleton for using google maps. This project just contains a single activity and a map fragment. This is my short version of it:
public class MapsActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if(savedInstanceState == null){
getSupportFragmentManager().beginTransaction()
.add(R.id.wrapper, new SupportMapFragment(), "TEST")
.commit();
}
}
}
With this example I see a "redraw" problem. The map itself disappears for a second (just the map but not the whole map fragment because we can still see the map controls) when:
App is minimized and opened again
When user moves to another activity and moves back again to the map
This was captured on a Nexus4 (4.4.4). However I don't see this issue on another phone that has android 4.1.2.
Any ideas what might be wrong? Are there any solutions for this?
Update
Just found out the google maps app itself has this issue. So this must be a problem with the google maps build on android 4.4.4.
Created a bug report: https://code.google.com/p/android/issues/detail?id=77192&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars
Related
I am facing some strange behaviour on a Samsung Alpha (4.4.4). I have built an App with a MainActivity that has a FragmentTabHost with 4 different Fragments (Tabs). On each of these tabs you can search for different things, and when tap on one of them a new activity is being called and the details are being shown.
Now, when running the App on my Samsung S3 (4.2) and the emulator (4.4, Samsung S5) everything works fine, that means, when I click on the details and go back to my MainActivity I can still see my list entries (and all the other fragments are presistent in their state). Now, when I run my app on my gilfriends phone, Samsung Alpha 4.4.4, every time I turn back from the details activity onCreate is being called in my **MainActivity** and that of course means that all my fragments are being created again (so they are empty). How is it possible that the phones behave different and what can I do to to save my data ? I know that I can save my list entries and the restore them (and then I would have to restore all my fragments every time somebody clicks on the details), but I think, since it is working on my phone, maybe it is a flag or something I have to set.
This is how I have been restoring my lists after navigating back to my activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
registerForContextMenu(getView());
if (mPersonList == null)
mPersonList = new ArrayList<Person>();
mListView = (SwipeListView)getActivity().findViewById(R.id.liste_personen);
if (mPersonAdapter != null)
mPersonAdapter = new ArrayAdapterPerson(getActivity(), R.layout.zelle_person, mPersonList,mPersonAdapter.getGefilterteListe());
else
mPersonAdapter = new ArrayAdapterPerson(getActivity(), R.layout.zelle_person, mPersonList,mPersonList);
mListView.setAdapter(mPersonAdapter);
}
But since the activity, and so the fragment, is being newly created mPersonList is always null
My application only displays the map on Google maps. My problem is when I change the position of my screen (the application I installed on my tablet), turning it there's a white screen that appears before displaying the map.
My configuration; res / layout / main.xml and res / layout-land / main.xml to switch from portrait to landscape mode.
What should add or do to resolve this behavior?
Since you have specified the map fragment in the layout file, you can safely find it using findFragmentById in onCreate like so:
MapFragment mMapFragment; // this is neither GoogleMap or MapView!
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
initializeMap();
}
#Override
public void onResume() {
super.onResume();
// map init was already done in onCreate, will not do it twice
}
Then when you need the GoogleMap object you ask for it and have it delivered via a callback. When the callback executes, the map is guaranteed to be not null. This will work since Google Play services library v6.5.
private void initializeMap() {
mMapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
// googleMap will never be null here
// do not store it in a variable, always make a getMapAsync call
// do your map setup here
}
}
}
This is as quick as it gets so you shouldn't experience any flickering.
Note: In the original post you mentioned you had different layouts for portrait and landscape. If you really do, make sure both contain corresponding fragment IDs, otherwise you're bound to get exceptions. You also mentioned the layout was main.xml not activity_main.xml so make sure you use the layout you intended.
I solved my problem reading this (Activity restart on rotation Android) Activity restart on rotation Android
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();
}
}
When the application opens I create a new instance of a google map during onAttachedToWindow(), this works fine while the application is open. When I close the application and re-open it the google map does not load correctly, it just shows grey tiles.
#Override
public void onAttachedToWindow() {
if (hasCreated()) {
uiGoogleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_content_map_fragment)).getMap();
}
}
When should the google map be initialised to ensure it is loaded when the application is closed and re-opened?
EDIT:
I have tried initialising the map in onResume() and onCreate() and get the same problem
on Google API2 this hassle has been eliminated.
What you need to do is just initialize the map you created on your xml.
uiGoogleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map_content_map_fragment))
.getMap();
So when you close and re-open it it will be available. no need to override anything.
I think that the best place would be to create a class that extends SupportMapFragment, and initialise the map in:
#Override
public void onAttach(Activity activity)
Besides that though, I think if you initialise the map in onResume of the container activity it should be ok. But if you by initialising you mean adding the mapfragment to the activity, I would suggest doing it in the xml or in your activity's onCreate. Just my two pennies.
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);
}