How to change pedometer colors for iOS and Android?

My code uses a stapler that looks like this:

Step control

Does anyone know how I can change the color of Blue to Red for iOS and Android versions of a step by setting a new color in XAML? Please note that the latter need has been added to the text of generosity. Thanks

+6
source share
4 answers

This can be done using Effects .

Code

I created an example application here: https://github.com/brminnick/CustomStepper

Using effects in 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>

Stride color effect

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);
            }
        }
    }
}

Screenshots

Android

enter image description here

IOS

enter image description here

+7
source

iOS Android?

Xamarin.Android , , .

button_selector.xml button_border.xml Android Resources\drawable:

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-:

enter image description here

+3

You will need to create your own renderer. Looking at the source code, the native control for Stepper on iOS is UIStepper, while on Android it’s actually horizontal LinearLayoutwith two buttons. Therefore, for Android, the user renderer should update the background color of the buttons on iOS as well, they look like icons, so try changing it TintColor UIStepper.

0
source

I came up with a simple solution.

Shared file:

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
-1
source

All Articles