在 Xamarin Forms 中,我们可以使用 DependencyService 来调用原生方法。幸运的是,Android 文档提供了setLocalNightMode 方法来修改本地的DarkMode。需要注意的是,这个方法不能修改移动端Settings的配置。
现在我们可以创建一个IDarkModeService 接口:
public interface IDarkModeService
{
void SetDarkMode(bool value);
}
然后在Android方案中实现它的方法:
public class DarkModeService : IDarkModeService
{
public void SetDarkMode(bool value)
{
if (value)
{
MainActivity.instance.Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightYes);
MainActivity.instance.Recreate();
}
else
{
MainActivity.instance.Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightNo);
MainActivity.instance.Recreate();
}
}
}
这里我们需要从MainActivity
创建一个静态的
instance
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static MainActivity instance { set; get; }
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
instance = this;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
}
}
不要忘记在styles.xml 中添加配置以使应用支持DarkMode:
<style name="MainTheme" parent="Theme.AppCompat.DayNight.NoActionBar"></style>
最后,我们可以在 Xamarin Forms 中调用依赖方法如下:
private async void ShowDialog_Clicked(object sender, EventArgs e)
{
await DisplayAlert("Alert", "You have been alerted", "OK");
}
private void SetDarkMode_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IDarkModeService>().SetDarkMode(true);
}
private void CancelDarkMode_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IDarkModeService>().SetDarkMode(false);
}
效果:
===================================更新============ =======================
如果需要自定义每个主题的样式,可以在运行时交换主题。
首先,您可以在 Xamrin Forms 中存储主题标志(DarkMode):
private void SetDarkMode_Clicked(object sender, EventArgs e)
{
Preferences.Set("DarkMode", true);
DependencyService.Get<IDarkModeService>().SetDarkMode(true);
}
private void CancelDarkMode_Clicked(object sender, EventArgs e)
{
Preferences.Set("DarkMode", false);
DependencyService.Get<IDarkModeService>().SetDarkMode(false);
}
然后在 styles.xml 中添加每个 Theme 样式:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MainTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
</style>
<style name="DayTheme" parent="MainTheme">
</style>
<style name="NightTheme" parent="MainTheme" >
<item name="buttonBarPositiveButtonStyle">@style/positiveBtnStyle</item>
<item name="buttonBarNegativeButtonStyle">@style/negativeBtnstyle</item>
</style>
<!--style of sure button-->
<style name="positiveBtnStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">#0000ff</item>
</style>
<!--style of cancel button-->
<style name="negativeBtnstyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">#999999</item>
</style>
</resources>
最后,在 MainActivity.cs 中创建视图之前更改主题:
public static MainActivity instance { set; get; }
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
instance = this;
var darkMode = Preferences.Get("DarkMode", false);
if (darkMode)
{
this.SetTheme(Resource.Style.NightTheme);
}
else
{
this.SetTheme(Resource.Style.DayTheme);
}
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
现在我们可以看到按钮的颜色样式会发生变化: