Xamarin Forms Android端如何实现Picker运行时动态切换明暗主题
Xamarin.Forms Android端Picker主题切换实现方案
完整实现代码
[assembly: ExportRenderer(typeof(Picker), typeof(CustomPickerRenderer))] namespace CykelStaden.Droid.Renderers { public class CustomPickerRenderer : PickerRenderer { // 存储当前主题状态,可根据项目实际初始化默认值 private bool _isDarkTheme = false; public CustomPickerRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<Picker> e) { base.OnElementChanged(e); if (e.OldElement != null) { // 元素替换时取消旧订阅,避免内存泄漏 MessagingCenter.Unsubscribe<object, string>(this, "ThemeIsDark"); MessagingCenter.Unsubscribe<object, string>(this, "ThemeIsLight"); } if (e.NewElement != null && Control != null) { // 订阅主题切换通知 MessagingCenter.Subscribe<object, string>(this, "ThemeIsDark", (sender, arg) => { _isDarkTheme = true; UpdatePickerStyle(); }); MessagingCenter.Subscribe<object, string>(this, "ThemeIsLight", (sender, arg) => { _isDarkTheme = false; UpdatePickerStyle(); }); // 初始化时同步当前主题样式 UpdatePickerStyle(); } } // 更新Picker输入框本身的样式 private void UpdatePickerStyle() { if (_isDarkTheme) { // 暗主题配置:文字白色、下划线白色 Control.SetTextColor(Android.Graphics.Color.White); Control.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Android.Graphics.Color.White); } else { // 亮主题配置:文字黑色、下划线灰色 Control.SetTextColor(Android.Graphics.Color.Black); Control.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Android.Graphics.Color.Gray); } } // 重写弹窗创建逻辑,适配主题 protected override IElementListBuilder CreateDialog() { var dialogBuilder = base.CreateDialog(); var alertDialog = (AlertDialog)dialogBuilder; if (alertDialog != null) { var dialogList = alertDialog.ListView; if (_isDarkTheme) { // 暗主题弹窗配置:背景深灰、文字白色 alertDialog.Window.SetBackgroundDrawableResource(Android.Resource.Color.BackgroundDark); dialogList.SetBackgroundColor(Android.Graphics.Color.DarkGray); dialogList.CacheColorHint = Android.Graphics.Color.White; } else { // 亮主题弹窗配置:背景白色、文字黑色 alertDialog.Window.SetBackgroundDrawableResource(Android.Resource.Color.BackgroundLight); dialogList.SetBackgroundColor(Android.Graphics.Color.White); dialogList.CacheColorHint = Android.Graphics.Color.Black; } } return dialogBuilder; } protected override void Dispose(bool disposing) { if (disposing) { // 释放资源时确认取消所有订阅 MessagingCenter.Unsubscribe<object, string>(this, "ThemeIsDark"); MessagingCenter.Unsubscribe<object, string>(this, "ThemeIsLight"); } base.Dispose(disposing); } } }
注意事项
- 如果项目使用了Material Design主题,可将硬编码的颜色替换为项目资源中定义的主题色,样式一致性更好
- 需要适配Android 10以下系统暗模式的话,可在Resources/values目录下新增亮/暗两套style资源,切换时动态加载即可
- 代码中新增的订阅取消逻辑可同步到iOS端的实现中,避免出现内存泄漏问题
内容的提问来源于stack exchange,提问作者Jaser
相关产品推荐
相关产品推荐

