我有Xamarin.Forms
个应用,我创建了一个自定义Switch
,如下所示:
public class ExtSwitch : Switch
{
public static readonly BindableProperty SwitchOnColorProperty =
BindableProperty.Create(nameof(SwitchOnColor),
typeof(Color), typeof(ExtSwitch), Color.Default);
public Color SwitchOnColor
{
get { return (Color)GetValue(SwitchOnColorProperty); }
set { SetValue(SwitchOnColorProperty, value); }
}
// More codes here //
}
在我的XAML
我用过它:
<local:ExtSwitch Grid.Column = "2"
IsToggled="{Binding IsToggled}"
Toggled="Handle_Toggled"
SwitchThumbColor="White"
SwitchOnColor="Red"
SwitchOffColor="Gray"
HorizontalOptions="End"
VerticalOptions="Center" />
在我的C#代码中,我有一个Handle_Toggled
方法来处理Swich切换时发生的事情。但不知何故,Toggled
事件在我的自定义开关中使用时没有被触发,但在普通开关中使用时效果很好。
有人能指出我在这里错过了什么,或者我做错了什么?
修改
iOS中的自定义渲染器:
class ExtSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || e.NewElement == null) return;
ExtSwitch s = Element as ExtSwitch;
UISwitch sw = new UISwitch();
sw.ThumbTintColor = s.SwitchThumbColor.ToUIColor();
sw.OnTintColor = s.SwitchOnColor.ToUIColor();
SetNativeControl(sw);
}
}
使用上面的代码:
使用下面建议的代码:
Android中的自定义渲染器:
public class ExtSwitchRenderer : SwitchRenderer
{
public ExtSwitchRenderer(Context context) : base(context) { }
ExtSwitch s;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Switch> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || e.NewElement == null)
return;
s = Element as ExtSwitch;
if (this.Control != null)
{
if (this.Control.Checked)
{
this.Control.TrackDrawable.SetColorFilter(s.SwitchOnColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
}
else
{
this.Control.TrackDrawable.SetColorFilter(s.SwitchOffColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
}
this.Control.CheckedChange += this.OnCheckedChange;
}
Control.Toggle();
}
void OnCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
{
if (this.Control.Checked)
{
this.Control.ThumbDrawable.SetColorFilter(s.SwitchOnColor.ToAndroid(), PorterDuff.Mode.Multiply);
this.Control.TrackDrawable.SetColorFilter(s.SwitchOnColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
}
else
{
this.Control.ThumbDrawable.SetColorFilter(s.SwitchOffColor.ToAndroid(), PorterDuff.Mode.Multiply);
this.Control.TrackDrawable.SetColorFilter(s.SwitchOffColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
}
}
}
答案 0 :(得分:1)
在IO渲染器上
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || e.NewElement == null) return;
CustomSwitch s = Element as CustomSwitch;
//this.Control.ThumbTintColor = s.SwitchThumbColor.ToUIColor();
this.Control.OnTintColor = s.SwitchOnColor.ToUIColor();
}
和OnCheckedChange中的Android渲染器
private void OnCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
{
if (this.Control.Checked)
{
this.Control.TrackDrawable.SetColorFilter(view.SwitchOnColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
}
else
{
this.Control.TrackDrawable.SetColorFilter(view.SwitchOffColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
}
Element.IsToggled = Control.Checked;
}
答案 1 :(得分:0)
不要设置本机控件,而只是更新当前的Control,如下所示:
this.Control.ThumbTintColor = s.SwitchThumbColor.ToUIColor();
this.Control.OnTintColor = s.SwitchOnColor.ToUIColor();
并且无需致电SetNativeControl
答案 2 :(得分:0)
SetColorFilter
同时被弃用。使用 Xamarin.AndroidX.Core 包,您可以像这样使用渲染器:
public class ColoredSwitchRenderer : SwitchRenderer
{
private readonly Android.Graphics.Color _defaultColor = ((Color)Application.Current.Resources["Default"]).ToAndroid();
private readonly Android.Graphics.Color _activeColor = ((Color)Application.Current.Resources["Active"]).ToAndroid();
private readonly Android.Graphics.Color _inactiveColor = ((Color)Application.Current.Resources["Inactive"]).ToAndroid();
public ColoredSwitchRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Switch> e)
{
base.OnElementChanged(e);
if (Control == null)
{
return;
}
SetThumbColor();
UpdateTrackColors();
Control.CheckedChange += OnCheckedChange;
}
private void SetThumbColor()
{
var filter = BlendModeColorFilterCompat.CreateBlendModeColorFilterCompat(_defaultColor, BlendModeCompat.SrcAtop);
Control.ThumbDrawable.SetColorFilter(filter);
}
private void OnCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
{
UpdateTrackColors();
Element.IsToggled = Control.Checked;
}
private void UpdateTrackColors()
{
if (Control.Checked)
{
var filter = BlendModeColorFilterCompat.CreateBlendModeColorFilterCompat(_activeColor, BlendModeCompat.Src);
Control.TrackDrawable?.SetColorFilter(filter);
}
else
{
var filter = BlendModeColorFilterCompat.CreateBlendModeColorFilterCompat(_inactiveColor, BlendModeCompat.Src);
Control.TrackDrawable?.SetColorFilter(filter);
}
}
protected override void Dispose(bool disposing)
{
Control.CheckedChange -= OnCheckedChange;
base.Dispose(disposing);
}
}
为了完整起见,iOS 渲染器:
public class ColoredSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Application.Current.Resources.TryGetValue("Active", out var activeColor);
Control.OnTintColor = ((Color)activeColor).ToUIColor();
Application.Current.Resources.TryGetValue("Default", out var defaultColor);
Control.ThumbTintColor = ((Color)defaultColor).ToUIColor();
Application.Current.Resources.TryGetValue("Inactive", out var inactiveColor);
Control.Subviews[0].Subviews[0].BackgroundColor = ((Color)inactiveColor).ToUIColor();
}
}
}