После дня выяснения, как решить эту проблему, я наконец-то смог показать тень.
По умолчанию Android предоставляет эту кнопку для рисования по умолчанию:
<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>
В формах Xamarinпри настройке пользовательского фона (например, <Button BackgroundColor="Red" Text="Ok"/>
) он создает рисование без отступов и вставок, таким образом скрывая любые контуры или тени кнопки.Вот почему кнопка с заданным цветом фона выглядит больше по сравнению с кнопкой по умолчанию без цвета фона.Вы можете установить HeightRequest
кнопки, чтобы сделать ее меньше, но тень все равно не появится.
В качестве обходного пути для устройств> = API 21, я создал два рисуемых XML-файла под Resources/drawable-v21
.папка а именно drawable_ripple_dark
и drawable_ripple_light
.Они будут использоваться для кнопок с темным или светлым цветом фона соответственно:
<?xml version="1.0" encoding="utf-8" ?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/ripple_material_dark"> <!-- or android:color="@color/ripple_material_light" -->
<item android:id="@+id/inset_drawable">
<inset 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:colorAccent" />
<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>
</item>
</ripple>
Это будет использоваться в качестве "шаблона" для рисования в моем пользовательском классе визуализации:
[assembly: ExportRenderer(typeof(MaterialButton), typeof(MaterialButtonRenderer))]
namespace XF.Material.Droid.Renderers
{
public class MaterialButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
private MaterialButton _materialButton;
public MaterialButtonRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (e?.NewElement != null)
{
_materialButton = this.Element as MaterialButton;
this.Control.SetAllCaps(true);
if (Material.IsLollipop)
{
this.Control.Background = this.CreateRippleDrawable();
}
}
}
private Drawable CreateRippleDrawable()
{
var normalColor = _materialButton.BackgroundColor.ToAndroid();
var cornerRadius = _materialButton.CornerRadius.ConvertDpToPx();
var borderWidth = (int)MaterialExtensions.ConvertDpToPx((int)_materialButton.BorderWidth);
var borderColor = _materialButton.BorderColor.ToAndroid();
var rippleDrawable = (normalColor.IsColorDark() ? ContextCompat.GetDrawable(this.Context, Resource.Drawable.drawable_ripple_dark) as RippleDrawable : ContextCompat.GetDrawable(this.Context, Resource.Drawable.drawable_ripple_light) as RippleDrawable).GetConstantState().NewDrawable().Mutate() as RippleDrawable; //Copies the drawable
var insetDrawable = rippleDrawable.FindDrawableByLayerId(Resource.Id.inset_drawable) as InsetDrawable;
var gradientDrawable = insetDrawable.Drawable as GradientDrawable;
gradientDrawable.SetCornerRadius(cornerRadius);
gradientDrawable.SetColor(normalColor);
gradientDrawable.SetStroke(borderWidth, borderColor);
return rippleDrawable;
}
}
}
СейчасЯ могу показать тень.Он также поднимается при прикосновении.