Xamarin形成Android Button材质阴影

时间:2018-06-23 10:11:01

标签: android xamarin xamarin.forms xamarin.android

我正在尝试在android中实现带有阴影的按钮。如您在此image中所看到的,我有3种类型的按钮。

左侧按钮是使用此按钮的默认按钮:<Button FontSize="14" Text="Button" />阴影已定义,并在按下时可以正确设置动画效果。

中间是这样的:<Button FontSize="14" Text="Button" BackgroundColor="Red" TextColor="White" />更改背景颜色会使按钮更高,并去除阴影。

右边的我使用了自定义渲染器,并使用了自定义ViewOutlineProvider并将其分配给控件的View.OutlineProvider属性。标记是这样的:<ctrl:MaterialButton FontSize="14" Text="Discard Changes" BackgroundColor="#6200EE" HeightRequest="36" TextColor="White" />

这是自定义渲染器类:

[assembly: ExportRenderer(typeof(MaterialButton), typeof(MaterialButtonRenderer))]
namespace XF.Material.Droid.Renderers
{

    public class MaterialButtonRenderer : Xamarin.Forms.Platform.Android.ButtonRenderer
    {
        private MaterialButton _materialButton;

        public MaterialButtonRenderer(Context context) : base(context) { }

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

            if (e?.NewElement != null)
            {
                _materialButton = this.Element as MaterialButton;
                this.Control.Text = this.Control.Text.ToUpper();
                this.Control.OutlineProvider = new MaterialButtonOutlineProvider(_materialButton.CornerRadius);
            }
        }

        private class MaterialButtonOutlineProvider : ViewOutlineProvider
        {
            private readonly int _cornerRadius;

            public MaterialButtonOutlineProvider(int cornerRadius)
            {
                _cornerRadius = cornerRadius;
            }

            public override void GetOutline(Android.Views.View view, Outline outline)
            {
                var cornerRadius = MaterialExtensions.ConvertDpToPx(_cornerRadius);
                outline.SetRoundRect(0, 0, view.Width, view.Height, cornerRadius);
            }
        }
    }
}

我还尝试在渲染器中设置View.ElevationView.TranslationZ属性,但仍然没有阴影。如果您仔细看一下右键的角,您会看到一个轮廓,但它似乎已被剪掉。

2 个答案:

答案 0 :(得分:1)

经过一天的摸索后,我终于可以露出阴影了。

默认情况下,Android提供此默认按钮drawable:

s/and

在Xamarin Forms中,设置自定义背景(即WindowManager.LayoutParams layoutParams = progressDialog.getWindow().getAttributes(); layoutParams.dimAmount = 0.5f; //Ranges from 0 to 1. progressDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); progressDialog.getWindow().setAttributes(layoutParams); )时,它会创建一个没有填充和插图的可绘制对象,从而隐藏了按钮的任何轮廓或阴影。这就是为什么与没有背景色的默认按钮相比,定义了背景色的按钮看起来更大的原因。您可以设置按钮的<inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="@dimen/abc_button_inset_horizontal_material" android:insetTop="@dimen/abc_button_inset_vertical_material" android:insetRight="@dimen/abc_button_inset_horizontal_material" android:insetBottom="@dimen/abc_button_inset_vertical_material"> <shape android:shape="rectangle"> <corners android:radius="@dimen/abc_control_corner_material" /> <solid android:color="@android:color/white" /> <padding android:left="@dimen/abc_button_padding_horizontal_material" android:top="@dimen/abc_button_padding_vertical_material" android:right="@dimen/abc_button_padding_horizontal_material" android:bottom="@dimen/abc_button_padding_vertical_material" /> </shape> </inset> 使其更小,但阴影仍然不会出现。

要解决设备> = API 21的问题,我在<Button BackgroundColor="Red" Text="Ok"/>文件夹下创建了两个可绘制的XML文件,分别为HeightRequestResources/drawable-v21。这些将分别用于具有深色或浅色背景的按钮:

drawable_ripple_dark

这将在我的自定义渲染器类中用作“模板”可绘制对象:

drawable_ripple_light

现在,我可以show阴影了。触摸时也会升高。

答案 1 :(得分:0)

您有任何有关如何集成解决方案的示例吗?

我放了您的代码,由于该部分不知道变量MaterialButton,所以它会生成一些细节

[assembly: ExportRenderer (typeof (MaterialButton), typeof (MaterialButtonRenderer))]

该变量也不是

private MaterialButton _materialButton;

您导入了任何金块吗?或者除此之外,您还做了什么?

问候。