RUDE

Настройка высоты на пользовательской кнопке управления не работает

Я пытаюсь добиться наличия кнопки, как на этом снимке экрана:

Настройка высоты на пользовательской кнопке управления не работает

Итак, я сделал собственный элемент управления с помощью специального рендерера для iOS и Android, элемент управления ниже:

public class ElevationButton : Button
{
    public float Elevation
    {
        get => (float)GetValue(ElevationProperty);
        set => SetValue(ElevationProperty, value);
    }

    public static BindableProperty ElevationProperty = BindableProperty.Create(nameof(Elevation), typeof(float), typeof(ElevationButton), 4.0f);
}

а вот рендеринг iOS:

public class ElevationButtonRenderer : ButtonRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement == null)
            return;
    }

    public override void Draw(CGRect rect)
    {
        base.Draw(rect);
        UpdateShadow();
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        var element = (ElevationButton)this.Element;
        if (e.PropertyName == nameof(element.Elevation))
            UpdateShadow();
    }

    private void UpdateShadow()
    {
        var element = (ElevationButton)this.Element;

        Layer.ShadowRadius = element.Elevation;
        Layer.ShadowColor = UIColor.Gray.CGColor;
        Layer.ShadowOffset = new CGSize(2, 2);
        Layer.ShadowOpacity = 0.80f;
        Layer.ShadowPath = UIBezierPath.FromRect(Layer.Bounds).CGPath;
        Layer.MasksToBounds = false;
    }
}

и Android:

public class ElevationButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
    public ElevationButtonRenderer(Context context) : base(context) { }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement == null)
            return;

        var element = (ElevationButton)this.Element;

        // we need to reset the StateListAnimator to override the setting of Elevation on touch down and release.
        Control.StateListAnimator = new Android.Animation.StateListAnimator();

        // set the elevation manually
        ViewCompat.SetElevation(this, element.Elevation);
        ViewCompat.SetElevation(Control, element.Elevation);
    }

    public override void Draw(Canvas canvas)
    {
        var element = (ElevationButton)this.Element;
        Control.Elevation = element.Elevation;
        base.Draw(canvas);
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        var element = (ElevationButton)this.Element;
        if (e.PropertyName == nameof(element.Elevation))
        {
            ViewCompat.SetElevation(this, element.Elevation);
            ViewCompat.SetElevation(Control, element.Elevation);
            UpdateLayout();
        }
    }
}

Вот xaml, в котором я объявляю пользовательский элемент управления:

<StackLayout Orientation="Horizontal">
                    <StackLayout Orientation="Vertical">
                        <controls:ElevationButton x:Name="buttonTest"
                            BackgroundColor="White"
                            HeightRequest="40"
                            WidthRequest="40"
                            Elevation="20"
                            CornerRadius="50"
                            Padding="10,10,10,10"
                            Text="{x:Static fa:FontAwesomeIcons.Camera}" 
                            FontFamily="FASolid" 
                            TextColor="{StaticResource Text}" />
                        <Label Text="PHOTO" />
                    </StackLayout>

Итак, когда я тестирую этот код, рендеринг выглядит так, что не отображает высоту и тень, независимо от того, какое значение я устанавливаю для свойства Elevation:

Настройка высоты на пользовательской кнопке управления не работает

Я видел в других сообщениях, что есть некоторые проблемы с CornerRadius, в моем случае с ним или без него высота не отображается.

Если у вас есть какие-либо идеи, я был бы рад прочитать это.


31
1

Ответ:

Решено

Если вам просто нужна тень, вы можете использовать Community Toolkit.

Установить из NuGet: https://www.nuget.org/packages/Xamarin.CommunityToolkit/2.0.1?_src=template

Xaml:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         xmlns:controls="clr-namespace:App1"
         xmlns:xct="http://xamarin.com/schemas/2020/toolkit"         
         x:Class="App1.Page6">

<StackLayout Orientation="Horizontal">
    <StackLayout Orientation="Vertical">
        <controls:ElevationButton x:Name="buttonTest"
                        BackgroundColor="White"
                        .......
                        xct:ShadowEffect.Color="Red" 
                        xct:ShadowEffect.OffsetY="12"                       />
        <Label Text="PHOTO" />
    </StackLayout>
</StackLayout>

  

</ContentPage>

enter image description here