Как изменить цвета степпера для iOS и Android?
5 ответов
Это можно сделать с помощью эффекты.
код
Я создал образец приложения здесь:https://github.com/brminnick/CustomStepper
потребление эффектов в XAML
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CustomStepper.StepperPage"
xmlns:local="clr-namespace:CustomStepper">
<ContentPage.Content>
<StackLayout
HorizontalOptions="Center"
VerticalOptions="Center">
<local:RedStepper/>
<Stepper
local:StepperColorEffect.Color="Red"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Шаговый Цветовой Эффект
using System.Linq;
using Xamarin.Forms;
namespace CustomStepper
{
public static class StepperColorEffect
{
public static readonly BindableProperty ColorProperty =
BindableProperty.CreateAttached(nameof(Color),
typeof(Color),
typeof(Stepper),
Color.Gray,
propertyChanged: OnStepperColorChanged);
public static Color GetColor(BindableObject view) => (Color)view.GetValue(ColorProperty);
public static void SetColor(BindableObject view, Color value) => view.SetValue(ColorProperty, value);
static void OnStepperColorChanged(BindableObject bindable, object oldValue, object newValue) => UpdateEffect(bindable);
static void UpdateEffect(BindableObject bindable)
{
switch (bindable)
{
case Stepper stepper:
RemoveEffect(stepper);
stepper.Effects.Add(new StepperColorRoutingEffect());
break;
}
}
static void RemoveEffect(Stepper entry)
{
var effectToRemoveList = entry.Effects.Where(e => e is StepperColorRoutingEffect).ToList();
foreach (var entryReturnTypeEffect in effectToRemoveList)
entry.Effects.Remove(entryReturnTypeEffect);
}
}
class StepperColorRoutingEffect : RoutingEffect
{
public StepperColorRoutingEffect() : base("CustomStepper.StepperColorEffect")
{
}
}
}
iOS PlatformEffect
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using CustomStepper.iOS;
[assembly: ResolutionGroupName("CustomStepper")]
[assembly: ExportEffect(typeof(StepperColorEffect), nameof(StepperColorEffect))]
namespace CustomStepper.iOS
{
public class StepperColorEffect : PlatformEffect
{
protected override void OnAttached()
{
if (Element is Stepper element && Control is UIStepper control)
control.TintColor = CustomStepper.StepperColorEffect.GetColor(element).ToUIColor();
}
protected override void OnDetached()
{
if (Element is Stepper element && Control is UIStepper control)
control.TintColor = UIColor.Blue;
}
}
}
Android PlatformEffect
using Android.Widget;
using Android.Graphics;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using CustomStepper.Droid;
[assembly: ResolutionGroupName("CustomStepper")]
[assembly: ExportEffect(typeof(StepperColorEffect), nameof(StepperColorEffect))]
namespace CustomStepper.Droid
{
public class StepperColorEffect : PlatformEffect
{
protected override void OnAttached()
{
if (Element is Stepper element && Control is LinearLayout control)
{
control.GetChildAt(0).Background.SetColorFilter(CustomStepper.StepperColorEffect.GetColor(element).ToAndroid(), PorterDuff.Mode.Multiply);
control.GetChildAt(1).Background.SetColorFilter(CustomStepper.StepperColorEffect.GetColor(element).ToAndroid(), PorterDuff.Mode.Multiply);
}
}
protected override void OnDetached()
{
if (Element is Stepper element && Control is LinearLayout control)
{
control.GetChildAt(0).Background.SetColorFilter(Xamarin.Forms.Color.Gray.ToAndroid(), PorterDuff.Mode.Multiply);
control.GetChildAt(1).Background.SetColorFilter(Xamarin.Forms.Color.Gray.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
}
}
скриншоты
Android
iOS
как я могу изменить цвета степпера для iOS и Android?
в своем Xamarin.Android
проект, вы можете создать пользовательский вектор drawable и использовать его в качестве фона для достижения того же внешнего вида, как изображение у вас есть сообщение выше.
место button_selector.xml
и button_border.xml
файл в вашем Android :
button_selector.в XML
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/colorAccent" android:state_pressed="true"/>
<item android:drawable="@color/colorPrimaryDark" android:state_focused="true"/>
<item android:drawable="@drawable/button_border"/>
</selector>
button_border.XML-код:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#00FFFFFF" />
<corners android:radius="5dp" />
<stroke
android:width="2dp"
android:color="#FFFFFF" />
</shape>
в вашей ExtStepperRenderer
:
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
MyStepper s = Element as MyStepper;
if (Control != null)
{
var button = Control.GetChildAt(0) as Android.Widget.Button;
button.SetTextColor(s.MyColor.ToAndroid());
button.SetBackground(ResourcesCompat.GetDrawable(Resources, Resource.Drawable.button_selector, null));
button.Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
var button2 = Control.GetChildAt(1) as Android.Widget.Button;
button2.SetTextColor(s.MyColor.ToAndroid());
button2.SetBackground(ResourcesCompat.GetDrawable(Resources, Resource.Drawable.button_selector, null));
button2.Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
эффект на устройстве Android:
вам нужно будет создать пользовательский визуализатор. Глядя на исходный код, собственный элемент управления для Stepper on iOS is UIStepper
и Android это на самом деле горизонтальный LinearLayout
с двумя кнопками. Поэтому для Android пользовательский рендерер должен обновлять цвет фона кнопок, а на iOS они кажутся значками, поэтому попробуйте изменить TintColor
на UIStepper
.
Это мое решение, которое также ссылается на ответ @Alan2.
Xamarin.Формы
public class StepperExtend : Stepper
{
public static readonly BindableProperty ColorProperty =
BindableProperty.Create(
nameof(Color),
typeof(Color),
typeof(StepperExtend),
Color.Default);
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
}
Xamarin.Android
[assembly:ExportRenderer(typeof(StepperExtend), typeof(StepperExtendRenderer))]
пространство имен HydroUkPoc.Внешний интерфейс.Формы.Дроид.Визуализация { общественный класс StepperExtendRenderer : StepperRenderer { StepperExtend FormElement { get { return Element as StepperExtend; } }
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
if (Control != null)
{
UpdateColor();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == StepperExtend.ColorProperty.PropertyName)
{
UpdateColor();
}
else
{
base.OnElementPropertyChanged(sender, e);
}
}
private void UpdateColor()
{
Control.GetChildAt(0).Background.SetColorFilter(FormElement.Color.ToAndroid(), PorterDuff.Mode.Multiply);
Control.GetChildAt(1).Background.SetColorFilter(FormElement.Color.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
}
Xamarin.iOS
[assembly:ExportRenderer(typeof(StepperExtend), typeof(StepperExtendRenderer))]
пространство имен HydroUkPoc.Внешний интерфейс.Формы.усвн.Визуализация { общественный класс StepperExtendRenderer : StepperRenderer { StepperExtend FormElement { get { return Element as StepperExtend; } }
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
if (Control != null)
{
UpdateColor();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == StepperExtend.ColorProperty.PropertyName)
{
UpdateColor();
}
else
{
base.OnElementPropertyChanged(sender, e);
}
}
private void UpdateColor()
{
Control.TintColor = FormElement.Color.ToUIColor();
}
}
}
Я придумал простое решение.
Файл:
using Xamarin.Forms;
namespace Japanese
{
public class ExtStepper : Stepper
{
public static readonly BindableProperty ColorProperty =
BindableProperty.Create(nameof(Color),
typeof(Color), typeof(ExtStepper),
Color.Default);
public Color StepperColor
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
}
}
iOS
using Xamarin.Forms;
using Japanese;
using Japanese.iOS;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(ExtStepper), typeof(ExtStepperRenderer))]
namespace Japanese.iOS
{
public class ExtStepperRenderer : StepperRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
ExtStepper s = Element as ExtStepper;
if (Control != null)
Control.TintColor = s.StepperColor.ToUIColor();
}
}
}
Andoid
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Japanese;
using Japanese.Droid;
using Android.Content;
using Android.Graphics;
[assembly: ExportRenderer(typeof(ExtStepper), typeof(ExtStepperRenderer))]
namespace Japanese.Droid
{
public class ExtStepperRenderer : StepperRenderer
{
public ExtStepperRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
ExtStepper s = Element as ExtStepper;
if (Control != null)
{
Control.GetChildAt(0).Background.SetColorFilter(s.StepperColor.ToAndroid(), PorterDuff.Mode.Multiply);
Control.GetChildAt(1).Background.SetColorFilter(s.StepperColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
}
}
XAML
<local:ExtStepper StepperColor="Red" x:Name="rptStepper