Материал кнопки Xamarin Forms для Android Тень - PullRequest
0 голосов
/ 23 июня 2018

Я пытаюсь добиться кнопки с тенью в Android.Как вы можете видеть на этом изображении , у меня есть 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.Elevation и View.TranslationZ в рендерере, но все женет тениЕсли вы внимательно посмотрите на углы правой кнопки, вы можете увидеть контур, но он выглядит обрезанным.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

У вас есть примеры того, как интегрировать ваше решение?

Я поместил ваш код, и он генерирует некоторые детали, так как переменная MaterialButton в этой части неизвестна

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

ниэто переменная

private MaterialButton _materialButton;

Вы импортировали какой-нибудь самородок или что вы делали кроме этого?

Привет.

0 голосов
/ 24 июня 2018

После дня выяснения, как решить эту проблему, я наконец-то смог показать тень.

По умолчанию 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;
        }
    }
}

СейчасЯ могу показать тень.Он также поднимается при прикосновении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...