Xamarin android 渲染器:按钮第一次是圆形的,但是当按下后退按钮时它变成方形

Xamarin android renderer: button is round the first time, but when pressed on the backbutton it becomes square

我在 Android 中制作了一个渲染器来制作一个圆形按钮。当您正常进入页面时,它会执行没有问题。但是当你按下后退按钮返回那个页面时,按钮变成了一个正方形。

我的渲染器代码:

public class FloatingActionButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
    private GradientDrawable _normal, _pressed;

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
    {
        base.OnElementChanged(e);

        if (Control != null)
        {
            var button = (FloatingActionButton)e.NewElement;

            button.SizeChanged += OnSizeChanged;

        }
    }

    private void OnSizeChanged(object s, EventArgs e) {
        var button = (FloatingActionButton)s;
        var radius = (float)Math.Min(button.Width, button.Height) * Resources.DisplayMetrics.Density;

        // Create a drawable for the button's normal state
        _normal = new Android.Graphics.Drawables.GradientDrawable();

        if (button.BackgroundColor.R == -1.0 && button.BackgroundColor.G == -1.0 && button.BackgroundColor.B == -1.0)
            _normal.SetColor(Android.Graphics.Color.ParseColor("#ff2c2e2f"));
        else
            _normal.SetColor(button.BackgroundColor.ToAndroid());

        _normal.SetCornerRadius(radius);

        // Create a drawable for the button's pressed state
        _pressed = new Android.Graphics.Drawables.GradientDrawable();
        var highlight = Context.ObtainStyledAttributes(new int[] { Android.Resource.Attribute.ColorActivatedHighlight }).GetColor(0, Android.Graphics.Color.Gray);
        _pressed.SetColor(highlight);
        _pressed.SetCornerRadius(radius);

        // Add the drawables to a state list and assign the state list to the button
        var sld = new StateListDrawable();
        sld.AddState(new int[] { Android.Resource.Attribute.StatePressed }, _pressed);
        sld.AddState(new int[] { }, _normal);
        Control.SetBackground(sld);
        button.SizeChanged -= OnSizeChanged;
    }
}

所以我创建了一个大小更改处理程序。两次创建都没有问题,但它仅在您正常进入页面时才进入事件。按后退键不进入

浮动操作按钮截图: button

编辑 一些额外的信息: 我忘了提到我覆盖了我的 MasterDetailPageOnBackButtonPressed,我这样做是因为否则当我按下后退按钮时它会崩溃:

protected override bool OnBackButtonPressed()
{

    Page page = GoPrevPage();
    if (page.GetType() == typeof(LoginPage))
    {
        App.Current.MainPage = new LoginPage();
    }

    else
    {
        page.Parent = null;
        Detail = page;

        navigationDrawerList.SelectedItem = selectedMenuItems.LastOrDefault();

    }
    return true;
}

GoPrevPage 是静态函数class:

public static class BackButtonHelper
{
    public static List<Page> prevPages;
    public static List<MasterPageItem> selectedMenuItems;

    static BackButtonHelper() {
        prevPages = new List<Page>();
        selectedMenuItems = new List<MasterPageItem>();
    }

    public static Page GoPrevPage() {
        prevPages.RemoveAt(prevPages.Count - 1);
        selectedMenuItems.RemoveAt(selectedMenuItems.Count - 1);
        return prevPages[prevPages.Count - 1]; 
    }
    public static void AddPageToPrev(Page page, MasterPageItem masterPageItem)
    {

        if (!IsToegevoegd(page.ClassId))
        {
            prevPages.Add(page);
            selectedMenuItems.Add(masterPageItem);
        }


    }
    private static bool IsToegevoegd(string title) {

        return prevPages.Last().ClassId == title;
    }
}

这是当您点击操作按钮时发生的操作(导航:

private void insertTaak_Clicked(object sender, EventArgs e)
{
    var navPage = new DetailTaak("0") { Title = "Taak toevoegen" };

    var app = Application.Current as App;

    var mainPage = (MenuPage)app.MainPage;


    mainPage.Detail = new NavigationPageBar(navPage);
}

我说忘记尺寸变化事件,直接尝试更新

public class FloatingActionButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
    private GradientDrawable _normal, _pressed;

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
    {
        base.OnElementChanged(e);

        if (Control != null)
        {
            var button = (FloatingActionButton)e.NewElement;
            this.UpdateStyle(button);
        }
    }

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == FloatingActionButton.HeightProperty.PropertyName ||
            e.PropertyName == FloatingActionButton.WidthProperty.PropertyName)
        {
            var button = (FloatingActionButton)sender;
            UpdateStyle(button);
        }
        else
        {
            base.OnElementPropertyChanged(sender, e);
        }
    }

    private void UpdateStyle(FloatingActionButton button)
    {
        try
        {
            var radius = (float)Math.Min(button.Width, button.Height) * Resources.DisplayMetrics.Density;

            // Create a drawable for the button's normal state
            _normal = new Android.Graphics.Drawables.GradientDrawable();

            if (button.BackgroundColor.R == -1.0 && button.BackgroundColor.G == -1.0 && button.BackgroundColor.B == -1.0)
                _normal.SetColor(Android.Graphics.Color.ParseColor("#ff2c2e2f"));
            else
                _normal.SetColor(button.BackgroundColor.ToAndroid());

            _normal.SetCornerRadius(radius);

            // Create a drawable for the button's pressed state
            _pressed = new Android.Graphics.Drawables.GradientDrawable();
            var highlight = Context.ObtainStyledAttributes(new int[] { Android.Resource.Attribute.ColorActivatedHighlight }).GetColor(0, Android.Graphics.Color.Gray);
            _pressed.SetColor(highlight);
            _pressed.SetCornerRadius(radius);

            // Add the drawables to a state list and assign the state list to the button
            var sld = new StateListDrawable();
            sld.AddState(new int[] { Android.Resource.Attribute.StatePressed }, _pressed);
            sld.AddState(new int[] { }, _normal);
            Control.SetBackground(sld);
        }
        catch
        {
            //...No-op
        }
    }
}