2

I have Xamarin PCL app which uses Stepper. I wanted to change the color of my Stepper button and now using the following renderer.

In PCL:

public class MyStepper : Stepper
{
   public static readonly BindableProperty ColorProperty = 
            BindableProperty.Create(nameof(Color), typeof(Color), typeof(MyStepper), Color.Default);

   public Color MyColor
   {
      get { return (Color)GetValue(ColorProperty); }
      set { SetValue(ColorProperty, value); }
   }
}

In iOS:

public class MyStepperRenderer : StepperRenderer
{
   protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
   {
      base.OnElementChanged(e);
      MyStepper s = Element as MyStepper;

      if (Control != null)
         Control.TintColor = s.MyColor.ToUIColor();
   }
}

enter image description here

In Android:

protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
   base.OnElementChanged(e);
   MyStepper s = Element as MyStepper;

   if (Control != null)
   {
      Control.GetChildAt(0).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
      Control.GetChildAt(1).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
    }
}

enter image description here

In XAML:

<local:MyStepper MyColor="Red" Maximum="10" Minimum="0" ....... />

As expected it would work like the images attached. But is it possible to make the Android color to change just the "outline" of the button like what it looks like in iOS?

Sven-Michael Stübe
  • 14,560
  • 4
  • 52
  • 103
iamsophia
  • 786
  • 8
  • 25

2 Answers2

1

How about changing the colors of the - and + also to red. Is there a way to do that also?

Based on @Sven-Michael Stübe's answer, I add some code to change the "-" and "+" color:

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

Effectt.

go and create a the drawable with the states and set them in your Renderer instead of setting a single color.

Sven-Michael Stübe wanna say that if you set a single color as a background, then your Button will have no click effect. You could refer to: Material effect on button with background color for more detail information.

For example:

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>
York Shen
  • 9,014
  • 1
  • 16
  • 40
0

You can do it if you create a custom vector drawable

button_border.xml

Place this file in your Android Resources\drawable folder and ensure the build action is set to AndroidResource

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

MyStepperRenderer.cs

Then you just need to set it as background of your two buttons.

protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
    base.OnElementChanged(e);
    var s = Element as MyStepper;

    if (Control != null)
    {
        Control.GetChildAt(0).SetBackground(Resources.GetDrawable(Resource.Drawable.button_border));
        Control.GetChildAt(1).SetBackground(Resources.GetDrawable(Resource.Drawable.button_border));
        Control.GetChildAt(0).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
        Control.GetChildAt(1).Background.SetColorFilter(s.MyColor.ToAndroid(), PorterDuff.Mode.Multiply);
    }
}

This will look like: enter image description here

discussion

If you don't have many different colors, go and create a the drawable with the states and set them in your Renderer instead of setting a single color. So your user will get a better feedback.

Sven-Michael Stübe
  • 14,560
  • 4
  • 52
  • 103
  • Thanks, How about changing the colors of the - and + also to red. Is there a way to do that also? I only have the red color so could you explain what you mean by "set them in your renderer so your user will get a better feedback". – iamsophia Feb 04 '18 at 23:20