有没有办法可以自定义Switch颜色
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有没有办法可以自定义Switch颜色相关的知识,希望对你有一定的参考价值。
我的代码使用这样的标准开关:
<Switch HorizontalOptions="End" IsToggled="{Binding PbSwitch}" />
显示时,它看起来像是打开和关闭:
有没有办法自定义这个,所以我可以在ios和android中将开关的背景颜色设置为不同的颜色。我认为这需要一个自定义渲染器,但我不知道该怎么做。
建议的解决方案有问题:
答案
如果我明白你想要什么,你可能需要自定义渲染器才能达到这个效果。
首先,在PCL中使用颜色BindableProperty定义CustomSwitch(使用它可以设置值并在不同平台上使用)
CustomSwitch
public class CustomSwitch : Switch
{
public static readonly BindableProperty SwitchOffColorProperty =
BindableProperty.Create(nameof(SwitchOffColor),
typeof(Color), typeof(CustomSwitch),
Color.Default);
public Color SwitchOffColor
{
get { return (Color)GetValue(SwitchOffColorProperty); }
set { SetValue(SwitchOffColorProperty, value); }
}
public static readonly BindableProperty SwitchOnColorProperty =
BindableProperty.Create(nameof(SwitchOnColor),
typeof(Color), typeof(CustomSwitch),
Color.Default);
public Color SwitchOnColor
{
get { return (Color)GetValue(SwitchOnColorProperty); }
set { SetValue(SwitchOnColorProperty, value); }
}
public static readonly BindableProperty SwitchThumbColorProperty =
BindableProperty.Create(nameof(SwitchThumbColor),
typeof(Color), typeof(CustomSwitch),
Color.Default);
public Color SwitchThumbColor
{
get { return (Color)GetValue(SwitchThumbColorProperty); }
set { SetValue(SwitchThumbColorProperty, value); }
}
public static readonly BindableProperty SwitchThumbImageProperty =
BindableProperty.Create(nameof(SwitchThumbImage),
typeof(string),
typeof(CustomSwitch),
string.Empty);
public string SwitchThumbImage
{
get { return (string)GetValue(SwitchThumbImageProperty); }
set { SetValue(SwitchThumbImageProperty, value); }
}
}
Android
[assembly: ExportRenderer(typeof(CustomSwitch), typeof(CustomSwitchRenderer))]
namespace FormsApp.Android
{
public class CustomSwitchRenderer : SwitchRenderer
{
private CustomSwitch view;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Switch> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || e.NewElement == null)
return;
view = (CustomSwitch)Element;
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.JellyBean)
{
if (this.Control != null)
{
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);
}
this.Control.CheckedChange += this.OnCheckedChange;
UpdateSwitchThumbImage(view);
}
//Control.TrackDrawable.SetColorFilter(view.SwitchBGColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
private void UpdateSwitchThumbImage(CustomSwitch view)
{
if (!string.IsNullOrEmpty(view.SwitchThumbImage))
{
view.SwitchThumbImage = view.SwitchThumbImage.Replace(".jpg", "").Replace(".png", "");
int imgid = (int)typeof(Resource.Drawable).GetField(view.SwitchThumbImage).GetValue(null);
Control.SetThumbResource(Resource.Drawable.icon);
}
else
{
Control.ThumbDrawable.SetColorFilter(view.SwitchThumbColor.ToAndroid(), PorterDuff.Mode.Multiply);
// Control.SetTrackResource(Resource.Drawable.track);
}
}
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);
}
}
protected override void Dispose(bool disposing)
{
this.Control.CheckedChange -= this.OnCheckedChange;
base.Dispose(disposing);
}
}
}
iOS
[assembly: ExportRenderer(typeof(CustomSwitch), typeof(CustomSwitchRenderer))]
namespace FormsApp2.iOS
{
class CustomSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || e.NewElement == null) return;
CustomSwitch s = Element as CustomSwitch;
UISwitch sw = new UISwitch();
sw.ThumbTintColor = s.SwitchThumbColor.ToUIColor();
sw.OnTintColor = s.SwitchOnColor.ToUIColor();
SetNativeControl(sw);
}
}
}
Usage in Portable
<local:CustomSwitch Margin="50" SwitchOnColor="Red"/>
不要忘记在Xaml中添加xmlns(名称空间)
xmlns:local = "clr-namespace:YouAppName"
另一答案
我对IOS Xamarin Forms有类似的问题:
Change Switch color in IOS Xamarin Forms
我用下一个代码使用自定义渲染解决了它:
[assembly: ExportRenderer(typeof(MySwitch), typeof(CustomSwitchRenderer))]
namespace CheckMyBus.App.ios.Renderers
{
public class CustomSwitchRenderer: SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
Element.Toggled += ElementToggled;
base.OnElementChanged(e);
if (Control != null)
{
UpdateUiSwitchColor();
}
}
private void ElementToggled(object sender, ToggledEventArgs e)
{
UpdateUiSwitchColor();
}
private void UpdateUiSwitchColor()
{
var temp = Element as Switch;
if (temp.IsToggled)
{
Control.ThumbTintColor = Color.FromHex(ColorConstants.BlueHex).ToUIColor();
Control.OnTintColor = Color.FromHex(ColorConstants.OblueLightHex).ToUIColor();
}
else
{
Control.ThumbTintColor = Color.FromHex(ColorConstants.GrayHex).ToUIColor();
}
}
}
}
并在Android Xamarin Forms项目中完成使用
<item name="colorAccent">#6495ED</item>
在MainTheme.Base样式的style.xml中。
所以这看起来比创建自定义开关更简单,你需要这样的东西,所以CustomSwitchRenderer
可以工作:
public class MySwitch: Switch
{
}
在XAML中:
<myControls:MySwitch x:Name="" />
以上是关于有没有办法可以自定义Switch颜色的主要内容,如果未能解决你的问题,请参考以下文章
[SwitchPreference]代码中动态修改SwitchPreference的Thumb或Track颜色