I am currently developing an android app using Xamarin.Android. In this app, I use a DrawerLayout (from the Support library v4) to show my app content and a menu that I can open by pressing a button in the toolbar or by sliding to the right.
In the first part of the drawer (page content), i have a toolbar replacing the classic action bar, a search bar, and my MapFragment.
In the menu part, I have a scrollview containing a linearlayout, itself containing some elements like buttons, textviews, etc, that the user will use to connect or register.
The menu is sliding smoothly, every element is responding correctly, but the mapfragment is really in trouble showing the map. For a few seconds, it displays an empty grid, and I have to tap the fragment so a few parts of the map can load. Almost no controls are responding, sometimes a double tap will work after a lot of waiting, and it will take forever to load more precise tiles.
There is obviously something preventing my map from loading correctly, but I have no idea what it is.
Here is the map fragment :
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapFragment"
android:layout_marginTop="94dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
And here is how I load my map in the activity file (in the OnCreate function) :
MapFragment mapFrag = (MapFragment)FragmentManager.FindFragmentById(Resource.Id.mapFragment);
GoogleMap map = mapFrag.Map;
if(map != null)
{
// The GoogleMap object is ready to go (well, should be)
}
I followed this to create my map fragment : https://developer.xamarin.com/guides/android/platform_features/maps_and_location/maps/part_2_-_maps_api/
I can provide more information if needed. I have strictly no idea where this comes from. I used the exact same code in a test app (except it was in a simple linear layout, no drawer, and also, no margin) and it's working perfectly, this is why I'm confused.
Edit : let the emulator and my phone run the app while I was writing (took me at least five minutes) and it's still not responding properly. Tested on Genymotion emulator (API 16) and on my OnePlus One (API 21), same result.
Thanks in advance.
I am not sure why exactly it is "slow", it has to process and load the map.
If you are using the drawer layout this means each page is most likely a fragment already. This means you will have a fragment in a fragment. When I was implementing this for the MyDriving sample features at build I used a standard MapView widget inside the fragment and if I was in an Activity I used the MapFragment.
If using the MapView widget you should implement IOnMapReadyCallback in your fragment to gain access:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
HasOptionsMenu = true;
var view = inflater.Inflate(Resource.Layout.fragment_current_trip, null);
mapView = view.FindViewById<MapView>(Resource.Id.map);
mapView.OnCreate(savedInstanceState);
return view;
}
public override void OnActivityCreated(Bundle savedInstanceState)
{
mapView.GetMapAsync(this);
base.OnActivityCreated(savedInstanceState);
}
GoogleMap map;
MapView mapView;
public void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
}
It should be noted when you are using the MapView widget you must also clean up after it with:
#region MapView Lifecycle Events
public override void OnResume()
{
base.OnResume();
mapView?.OnResume();
}
public override void OnPause()
{
base.OnPause();
mapView?.OnPause();
}
public override void OnDestroy()
{
base.OnDestroy();
mapView?.OnDestroy();
}
public override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
mapView?.OnSaveInstanceState(outState);
}
public override void OnLowMemory()
{
base.OnLowMemory();
mapView?.OnLowMemory();
}
#endregion
If you are in an Activity and using the MapFragment then you should also use this same style although there is no need to set the events like the MapView control:
GoogleMap map;
SupportMapFragment mapFrag;
public async void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
//Set your layout
mapFrag = (SupportMapFragment) SupportFragmentManager.FindFragmentById(Resource.Id.map);
mapFrag.GetMapAsync(this);
}
I hope this helps