Why does tapping on a Button in a Grid move it in front of other UI in Xamarin Forms?
Summary
I would like to have more control over the Text rendering on a Button in Xamarin.Forms, so I am using a Grid which contains a Label and Button object. This gives me more control over the text, but it has the side effect of the Label being moved behind the Button when the Button is clicked.
Why does this happen? Shouldn't the ordering of UI be determined by the order in which the children are added to the Grid's Children?
Details
I have created the following code to test the problem in isolation:
// The grid can be added directly to a page
var grid = new Grid();
grid.Margin = new Thickness(100, 100);
grid.WidthRequest = 200;
grid.HeightRequest = 200;
var button = new Button();
button.WidthRequest = 80;
button.HorizontalOptions = LayoutOptions.Start;
button.VerticalOptions = LayoutOptions.Fill;
grid.Children.Add(button);
var label = new Label();
label.Text = "This is some text";
label.VerticalOptions = LayoutOptions.Fill;
label.InputTransparent = true;
grid.Children.Add(label);
The button is sized so that it only overlaps part of the text so that it is clear that the button moves in front of the Label.
Before tapping on the button, this is how the layout appears:
After tapping, the button moves in front of the label as shown in the following image:
I could make the Text have a tap gesture, but then the button wouldn't play its native effect when touched, so I'd like to keep that functionality by clicking on the button.
Is there a way to keep the label in front of the button after a click?
Edit
This has been tested on a Motorola Moto G7 running Android 10 and on an emulator running Android version 9.
Note that on the Android hardware the label remains behind the button permanently. On the emulator the label moves behind the button when the button is pushed, but then re-appears on top after the button is released.
I had done a demo and reappeared the problem. The issue will happend because of the fast renderers. Add the code 'Forms.SetFlags("UseLegacyRenderers");' to your MainActivity class before calling Forms.Init. Such as
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Forms.SetFlags("UseLegacyRenderers");
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}