如何更改iOS和Android步进器的颜色?
我的代码使用了一个如下所示的步进器:
:
有没有人知道如何通过在XAML中设置新颜色来为步进器的iOS和Android版本更改蓝色到红色? 请注意,最后的需要被添加到赏金的文本中。 谢谢
这可以使用效果来完成。
码
我在这里创建了一个示例应用程序: https : //github.com/brminnick/CustomStepper
在XAML中使用效果
步进色彩效果
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平台效果
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 Resources\drawable
文件夹中:
button_selector.xml
button_border.xml:
在你的ExtStepperRenderer
:
protected override void OnElementChanged(ElementChangedEventArgs 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设备的影响:
您需要创建自定义渲染器。 查看源代码, iOS上的Stepper的本机控件是UIStepper
,而在Android上它实际上是一个带有两个按钮的水平LinearLayout
。 因此对于Android,自定义渲染器应该更新按钮的背景颜色,而在iOS上,它们似乎是图标,因此请尝试更改TintColor
的UIStepper
。
这是我的解决方案,也可以参考@Alan2的答案。
Xamarin.Forms
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))]
namespace HydroUkPoc.Frontend.Forms.Droid.Renderer {public class StepperExtendRenderer:StepperRenderer {StepperExtend FormElement {get {return Element as StepperExtend; }}
protected override void OnElementChanged(ElementChangedEventArgs 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))]
namespace HydroUkPoc.Frontend.Forms.iOS.Renderer {public class StepperExtendRenderer:StepperRenderer {StepperExtend FormElement {get {return Element as StepperExtend; }}
protected override void OnElementChanged(ElementChangedEventArgs 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 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 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