Xamarin MasterDetailPage IsGestureEnabled Android Bug Hack
I've implemented a MasterDetailPage in an app which is used on one page for filtering a list. It's advised that it's placed at root level which means it's available for use on all pages.
Because on most pages it's not needed, the flyout master page is not wanted, but can be opened by swiping from the left margin.
There is a property on the control called IsGestureEnabled which should control whether the swipe gesture works or not, so I decided to apply it once and only have a button on the page control the IsPresented property to show and hide the master page.
This works fine on iOS, but not on Android. Initially the gesture is disabled, but as soon as the property changes, the gestures become active and start allowing swipe from left top open, once closed. I've not looked at the DrawerLayout, but I'm assuming the gestures are enabled to allow the user to swipe close, however the state is not reverted afterwards.
I had a look at the Renderer code and noticed on the IsGestureChanged property handling in the HandlePropertyChanged method, it calls onto a method called SetGestureState which sets the drawer locker mode:
void SetGestureState()
{
SetDrawerLockMode(_page.IsGestureEnabled ? LockModeUnlocked : LockModeLockedClosed);
}
So at first I was thinking I'd create a custom renderer to try and permenantly disable the gestures, but then I realised if we just toggle the IsGestureEnabled property, to make the property change and the method will get called and lock the drawer close.
I hooked the toggling onto the IsPresentedChanged event in the code-behind of my MasterDetailPage instance like this:
// Hack to re-disable drawer after close. Calls SetDrawerLockMode on Android
if(Device.RuntimePlatform == Device.Android)
{
IsPresentedChanged += (s, e) =>
{
if (IsPresented) return;
IsGestureEnabled = true;
IsGestureEnabled = false;
};
}
...and it works great!