我有一个标准的xamarin forms项目(包括iOS和安卓),使用shell进行导航。我已经使用合并的字典实现了主题。这是我用来应用主题的方法:
public class MyShellRenderer : ShellRenderer
{
protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(Xamarin.Forms.ShellItem shellItem)
{
return new MyShellBottomNavViewAppearanceTracker(this);
}
}
internal class MyShellBottomNavViewAppearanceTracker : IShellBottomNavViewAppearanceTracker
{
private MyShellRenderer myShellRenderer;
public MyShellBottomNavViewAppearanceTracker(MyShellRenderer myShellRenderer)
{
this.myShellRenderer = myShellRenderer;
}
Task SetAppTheme(PreferredTheme preferredTheme)
{
if (Application.Current is null)
return Task.CompletedTask;
BaseTheme defaultTheme;
if (Application.Current.RequestedTheme == OSAppTheme.Dark)
defaultTheme = new DarkTheme();
else
defaultTheme = new LightTheme();
return _mainThread.InvokeOnMainThreadAsync(() =>
{
BaseTheme theme = preferredTheme switch
{
PreferredTheme.Dark => new DarkTheme(),
PreferredTheme.Light => new LightTheme(),
PreferredTheme.Default => defaultTheme
};
CurrentTheme = theme;
ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
mergedDictionaries.Clear();
mergedDictionaries.Add(theme);
}
OnPreferenceChanged(preferredTheme);
});
}这适用于iOS系统,但在安卓系统上,ItemText的颜色并没有改变。当暗模式主题的背景颜色与取消选择的选项卡的颜色相同(或接近)时,这是一个问题。图标按预期呈现。
我已经尝试在android上实现了一个自定义渲染,如下所示:
public void ResetAppearance(BottomNavigationView bottomView)
{
//Get and set background color from theme
Xamarin.Forms.Color xfcolor = (Xamarin.Forms.Color)App.Current.Resources["PageBackgroundColor"];
Android.Graphics.Color acolor = xfcolor.ToAndroid();
bottomView.SetBackgroundColor(acolor);
//Get and set state colors for menu items text
Xamarin.Forms.Color xfSelectedColor = (Xamarin.Forms.Color)App.Current.Resources["ColorBlue"];
Android.Graphics.Color aSelectedColor = xfSelectedColor.ToAndroid();
Xamarin.Forms.Color xfDeselectedColor = (Xamarin.Forms.Color)App.Current.Resources["ColorGray"];
Android.Graphics.Color aDeselectedColor = xfDeselectedColor.ToAndroid();
int[][] states = new int[][]
{
new int[] {-Android.Resource.Attribute.Checked }, // unchecked
new int[] { Android.Resource.Attribute.Checked } // pressed
};
int[] colors = new int[]
{
aSelectedColor,
aDeselectedColor
};
ColorStateList colorStateList = new ColorStateList(states, colors);
bottomView.ItemTextColor = colorStateList;
...这在一定程度上是因为整个文本都应用了aSelectedColor。
这是SDK中的一个bug,还是我只是做错了什么?
发布于 2021-10-23 12:04:43
找到了解决方案(感谢James Montemagno!)
灵感找到了here
因此,出于一些奇怪的原因,使用mergedDictionaries不适用于安卓系统。
相反,我基于Hanselman.Forms示例进行了以下重写:
Task SetAppTheme(PreferredTheme preferredTheme)
{
if (Application.Current is null)
return Task.CompletedTask;
BaseTheme defaultTheme;
if (Application.Current.RequestedTheme == OSAppTheme.Dark)
defaultTheme = new DarkTheme();
else
defaultTheme = new LightTheme();
return _mainThread.InvokeOnMainThreadAsync(() =>
{
BaseTheme theme = preferredTheme switch
{
PreferredTheme.Dark => new DarkTheme(),
PreferredTheme.Light => new LightTheme(),
PreferredTheme.Default => defaultTheme
};
CurrentTheme = theme;
//Previous code
/*ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
mergedDictionaries.Clear();
mergedDictionaries.Add(theme);
}*/
//New code
var applicationResourceDictionary = Application.Current.Resources;
ManuallyCopyThemes(theme, applicationResourceDictionary);
OnPreferenceChanged(preferredTheme);
});
}
void ManuallyCopyThemes(ResourceDictionary fromResource, ResourceDictionary toResource)
{
foreach (var item in fromResource.Keys)
{
if (toResource.ContainsKey(item))
toResource[item] = fromResource[item];
else
toResource.Add(item, fromResource[item]);
}
}https://stackoverflow.com/questions/69679886
复制相似问题