I need to change the text color of a button when it is disabled, I have created a custom renderer for iOS and one for Android. The iOS worked perfectly, since the android does not change the color, I have also created triggers via styles and also does not solve.
How to make color swap work for Xamarin.Forms?
Android Renderer:
[assembly: ExportRenderer(typeof(Button), typeof(MyButtonRenderer))]
namespace xxxxxx.Droid.Renderers
{
public class MyButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (Control != null)
Control.SetTextColor(Color.White.ToAndroid());
if (e != null)
{
e.NewElement.TextColor = Color.White;
e.OldElement.TextColor = Color.White;
}
}
}
}
This state change is changed according to the CanExecute of my commands, this would be the default style applied.
Neither of these ways solves
I use VisualStateManager to add different styles for each button state: normal, focused, pressed, disabled
<Style TargetType="Button">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource ColorAccent}" />
<Setter Property="TextColor" Value="{StaticResource ColorForegroundIcon}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource ColorAccentTransparent}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource ColorAccentTransparent}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{DynamicResource ColorBackgroundDisabled}" />
<Setter Property="TextColor" Value="{DynamicResource ColorForegroundFaded}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
For more info and examples, check out: Understanding Visual State Manager in Xamarin Forms
For Android:
[assembly: ExportRenderer(typeof(Button), typeof(MyButtonRenderer))]
namespace Forms.Droid.Renderers
{
public class MyButtonRenderer : ButtonRenderer
{
public MyButtonRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Button> args)
{
base.OnElementChanged(args);
if (Control != null) SetColors();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(sender, args);
if (args.PropertyName == nameof(Button.IsEnabled)) SetColors();
}
private void SetColors()
{
Control.SetTextColor(Element.IsEnabled ? Element.TextColor.ToAndroid() : Android.Graphics.Color.Gray);
Control.SetBackgroundColor(Element.IsEnabled ? Element.BackgroundColor.ToAndroid() : Android.Graphics.Color.DarkGray);
}
}
}
For iOS:
[assembly: ExportRenderer(typeof(Button), typeof(MyButtonRenderer))]
namespace Forms.iOS.Renderers
{
public class MyButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> args)
{
base.OnElementChanged(args);
if (Control != null) SetColors();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnElementPropertyChanged(sender, args);
if (args.PropertyName == nameof(Button.IsEnabled)) SetColors();
}
private void SetColors()
{
Control.SetTitleColor(Element.IsEnabled ? Element.TextColor.ToUIColor() : UIColor.Gray, Element.IsEnabled ? UIControlState.Normal : UIControlState.Disabled);
Control.BackgroundColor = Element.IsEnabled ? Element.BackgroundColor.ToUIColor() : UIColor.DarkGray;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With