Xamarin.forms 开关不符合颜色设置的样式
我有一个问题,我的开关似乎只服从样式设置时,它是切换。我已经为其Xamarin.forms 开关不符合颜色设置的样式,xamarin.forms,Xamarin.forms,我有一个问题,我的开关似乎只服从样式设置时,它是切换。我已经为其ThumbColor和OnColor设置了两种状态的属性,在这两种状态下,它要么打开,要么关闭,如下所示: <Style x:Key="SwitchThemeMomentum" TargetType="Switch"> <Setter Property="IsToggled" Value="{Binding MomentumTog
ThumbColor
和OnColor
设置了两种状态的属性,在这两种状态下,它要么打开,要么关闭,如下所示:
<Style x:Key="SwitchThemeMomentum" TargetType="Switch">
<Setter Property="IsToggled" Value="{Binding MomentumToggled, Mode=TwoWay}"/>
<Style.Triggers>
<DataTrigger TargetType="Switch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="True">
<Setter Property="ThumbColor" Value="{StaticResource Green}"/>
<Setter Property="OnColor" Value="#CCEDED" />
<Setter Property="IsToggled" Value="True" />
</DataTrigger>
<DataTrigger TargetType="Switch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="False">
<Setter Property="ThumbColor" Value="{StaticResource LightGray}" />
<Setter Property="OnColor" Value="Red" />
<Setter Property="IsToggled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="SwitchThemeMomentum" TargetType="customcontrols:CustomSwitch">
<Setter Property="IsToggled" Value="{Binding MomentumToggled, Mode=TwoWay}"/>
<Style.Triggers>
<DataTrigger TargetType="customcontrols:CustomSwitch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="True">
<Setter Property="ThumbColor" Value="{StaticResource Green}"/>
<Setter Property="OffColor" Value="Transparent" />
<Setter Property="OnColor" Value="{StaticResource SwitchOn}" />
<Setter Property="IsToggled" Value="True" />
</DataTrigger>
<DataTrigger TargetType="customcontrols:CustomSwitch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="False">
<Setter Property="ThumbColor" Value="{StaticResource LightGray}" />
<Setter Property="OffColor" Value="{StaticResource Gray80}" />
<Setter Property="IsToggled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
我这样称呼它:
<Switch
x:Name="momentumSwitch"
HorizontalOptions="Start"
IsToggled="{Binding MomentumToggled, Mode=TwoWay}"
ScaleX="0.8"
ScaleY="0.8"
Style="{StaticResource SwitchThemeMomentum}"
VerticalOptions="Start" />
ThumbColor得到了正确的遵守,当我将其设置为红色时,我可以看到它发生了变化,但是,只有当IsToggled为false时,OnColor不能说是相同的;我哪里出错了?多亏了谷歌搜索和编写自定义渲染器: 和 解决方案如下:创建新的
CustomSwitch
控件,该控件将添加名为OffColor
的新Color
属性,如下所示:
public class CustomSwitch : Switch
{
public static readonly BindableProperty OffColorProperty =
BindableProperty.Create(nameof(CustomSwitch), typeof(Color), typeof(CustomSwitch));
public CustomSwitch()
{
OffColor = Color.Transparent;
}
public Color OffColor {
get => (Color) GetValue(OffColorProperty);
set => SetValue(OffColorProperty, value);
}
}
通过创建Android和iOS渲染器来使用此应用程序:
Android:
public class CustomSwitchRenderer : SwitchRenderer
{
public CustomSwitchRenderer(Context context): base(context) { }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
if(!element.IsToggled)
{
Control.TrackTintList = ColorStateList.ValueOf(element.OffColor.ToAndroid());
}
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
var maskView = new UIView(Control.Frame)
{
BackgroundColor = element.IsToggled ? element.OnColor.ToUIColor() : element.OffColor.ToUIColor(),
ClipsToBounds = true
};
maskView.Layer.CornerRadius = Control.Frame.Height / 2;
Control.MaskView = maskView;
if(!element.IsToggled)
{
Control.TintColor = element.OffColor.ToUIColor();
Control.BackgroundColor = element.OffColor.ToUIColor();
} else
{
Control.TintColor = element.OnColor.ToUIColor();
Control.OnTintColor = element.OnColor.ToUIColor();
Control.BackgroundColor = element.OnColor.ToUIColor();
}
}
iOS:
public class CustomSwitchRenderer : SwitchRenderer
{
public CustomSwitchRenderer(Context context): base(context) { }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
if(!element.IsToggled)
{
Control.TrackTintList = ColorStateList.ValueOf(element.OffColor.ToAndroid());
}
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
var maskView = new UIView(Control.Frame)
{
BackgroundColor = element.IsToggled ? element.OnColor.ToUIColor() : element.OffColor.ToUIColor(),
ClipsToBounds = true
};
maskView.Layer.CornerRadius = Control.Frame.Height / 2;
Control.MaskView = maskView;
if(!element.IsToggled)
{
Control.TintColor = element.OffColor.ToUIColor();
Control.BackgroundColor = element.OffColor.ToUIColor();
} else
{
Control.TintColor = element.OnColor.ToUIColor();
Control.OnTintColor = element.OnColor.ToUIColor();
Control.BackgroundColor = element.OnColor.ToUIColor();
}
}
iOS更为复杂,因为你几乎必须创建Android版的TrackTintList,因为对于iOS来说,TintColor所做的只是将颜色应用到开关的边框上。面具就在那里,用来相应地填充它
最后,保持使用样式资源字典的精神,按如下方式更新样式:
<Style x:Key="SwitchThemeMomentum" TargetType="Switch">
<Setter Property="IsToggled" Value="{Binding MomentumToggled, Mode=TwoWay}"/>
<Style.Triggers>
<DataTrigger TargetType="Switch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="True">
<Setter Property="ThumbColor" Value="{StaticResource Green}"/>
<Setter Property="OnColor" Value="#CCEDED" />
<Setter Property="IsToggled" Value="True" />
</DataTrigger>
<DataTrigger TargetType="Switch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="False">
<Setter Property="ThumbColor" Value="{StaticResource LightGray}" />
<Setter Property="OnColor" Value="Red" />
<Setter Property="IsToggled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="SwitchThemeMomentum" TargetType="customcontrols:CustomSwitch">
<Setter Property="IsToggled" Value="{Binding MomentumToggled, Mode=TwoWay}"/>
<Style.Triggers>
<DataTrigger TargetType="customcontrols:CustomSwitch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="True">
<Setter Property="ThumbColor" Value="{StaticResource Green}"/>
<Setter Property="OffColor" Value="Transparent" />
<Setter Property="OnColor" Value="{StaticResource SwitchOn}" />
<Setter Property="IsToggled" Value="True" />
</DataTrigger>
<DataTrigger TargetType="customcontrols:CustomSwitch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="False">
<Setter Property="ThumbColor" Value="{StaticResource LightGray}" />
<Setter Property="OffColor" Value="{StaticResource Gray80}" />
<Setter Property="IsToggled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
重要提示:注意我们是如何将
TargetType
更新为我们的CustomSwitch
而不是默认的开关的;这是因为默认的开关
控件显然缺少OffColor
属性。多亏了一些谷歌搜索和编写自定义渲染器:
和
解决方案如下:创建新的CustomSwitch
控件,该控件将添加名为OffColor
的新Color
属性,如下所示:
public class CustomSwitch : Switch
{
public static readonly BindableProperty OffColorProperty =
BindableProperty.Create(nameof(CustomSwitch), typeof(Color), typeof(CustomSwitch));
public CustomSwitch()
{
OffColor = Color.Transparent;
}
public Color OffColor {
get => (Color) GetValue(OffColorProperty);
set => SetValue(OffColorProperty, value);
}
}
通过创建Android和iOS渲染器来使用此应用程序:
Android:
public class CustomSwitchRenderer : SwitchRenderer
{
public CustomSwitchRenderer(Context context): base(context) { }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
if(!element.IsToggled)
{
Control.TrackTintList = ColorStateList.ValueOf(element.OffColor.ToAndroid());
}
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
var maskView = new UIView(Control.Frame)
{
BackgroundColor = element.IsToggled ? element.OnColor.ToUIColor() : element.OffColor.ToUIColor(),
ClipsToBounds = true
};
maskView.Layer.CornerRadius = Control.Frame.Height / 2;
Control.MaskView = maskView;
if(!element.IsToggled)
{
Control.TintColor = element.OffColor.ToUIColor();
Control.BackgroundColor = element.OffColor.ToUIColor();
} else
{
Control.TintColor = element.OnColor.ToUIColor();
Control.OnTintColor = element.OnColor.ToUIColor();
Control.BackgroundColor = element.OnColor.ToUIColor();
}
}
iOS:
public class CustomSwitchRenderer : SwitchRenderer
{
public CustomSwitchRenderer(Context context): base(context) { }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
if(!element.IsToggled)
{
Control.TrackTintList = ColorStateList.ValueOf(element.OffColor.ToAndroid());
}
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(Control == null)
{
return;
}
var element = (CustomSwitch) Element;
var maskView = new UIView(Control.Frame)
{
BackgroundColor = element.IsToggled ? element.OnColor.ToUIColor() : element.OffColor.ToUIColor(),
ClipsToBounds = true
};
maskView.Layer.CornerRadius = Control.Frame.Height / 2;
Control.MaskView = maskView;
if(!element.IsToggled)
{
Control.TintColor = element.OffColor.ToUIColor();
Control.BackgroundColor = element.OffColor.ToUIColor();
} else
{
Control.TintColor = element.OnColor.ToUIColor();
Control.OnTintColor = element.OnColor.ToUIColor();
Control.BackgroundColor = element.OnColor.ToUIColor();
}
}
iOS更为复杂,因为你几乎必须创建Android版的TrackTintList,因为对于iOS来说,TintColor所做的只是将颜色应用到开关的边框上。面具就在那里,用来相应地填充它
最后,保持使用样式资源字典的精神,按如下方式更新样式:
<Style x:Key="SwitchThemeMomentum" TargetType="Switch">
<Setter Property="IsToggled" Value="{Binding MomentumToggled, Mode=TwoWay}"/>
<Style.Triggers>
<DataTrigger TargetType="Switch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="True">
<Setter Property="ThumbColor" Value="{StaticResource Green}"/>
<Setter Property="OnColor" Value="#CCEDED" />
<Setter Property="IsToggled" Value="True" />
</DataTrigger>
<DataTrigger TargetType="Switch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="False">
<Setter Property="ThumbColor" Value="{StaticResource LightGray}" />
<Setter Property="OnColor" Value="Red" />
<Setter Property="IsToggled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="SwitchThemeMomentum" TargetType="customcontrols:CustomSwitch">
<Setter Property="IsToggled" Value="{Binding MomentumToggled, Mode=TwoWay}"/>
<Style.Triggers>
<DataTrigger TargetType="customcontrols:CustomSwitch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="True">
<Setter Property="ThumbColor" Value="{StaticResource Green}"/>
<Setter Property="OffColor" Value="Transparent" />
<Setter Property="OnColor" Value="{StaticResource SwitchOn}" />
<Setter Property="IsToggled" Value="True" />
</DataTrigger>
<DataTrigger TargetType="customcontrols:CustomSwitch" Binding="{Binding MomentumToggled, Mode=TwoWay}" Value="False">
<Setter Property="ThumbColor" Value="{StaticResource LightGray}" />
<Setter Property="OffColor" Value="{StaticResource Gray80}" />
<Setter Property="IsToggled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
重要提示:注意我们是如何将TargetType
更新为我们的CustomSwitch
而不是默认的开关的;这是因为默认的Switch
控件显然缺少OffColor
属性。“OnColor是一种影响开关在切换或打开状态下呈现方式的颜色。”这是我的想法,但它没有“OffColor”属性,因此我希望它可能适用于这两种情况。这是否意味着解决方案涉及渲染器/效果?因此您希望颜色应用于两种状态?那么就没有清晰的视觉指示器来显示Off和OnYeah,这是有意义的,哦,好吧,是时候让效果非常快了。让我想知道为什么他们没有实现关闭开关颜色属性;或者至少使其适用于这两种设置,具体取决于它是切换还是未切换关闭颜色增强:,“OnColor是一种影响开关在切换或打开状态下的渲染方式的颜色。”这就是我所认为的名称,但它没有“OffColor”属性,因此我希望它可能适用于这两种设置。这是否意味着解决方案涉及渲染器/效果?因此您希望颜色应用于两种状态?那么就没有清晰的视觉指示器来显示Off和OnYeah,这是有意义的,哦,好吧,是时候让效果非常快了。让我想知道为什么他们没有实现关闭开关颜色属性;或者至少使其应用于这两种设置,具体取决于它是否处于关闭状态颜色增强:,