gpt4 book ai didi

xamarin - Android 以编程方式更改主题

转载 作者:行者123 更新时间:2023-12-01 22:05:47 26 4
gpt4 key购买 nike

我有一个 Multi-Tenancy 应用程序,必须在用户登录后切换主题。

到目前为止,当用户已经登录并启动应用程序时,我会在 MainActivity OnCreate 方法上调用 setTheme()。

这工作正常,应用程序以正确的主题显示。

但当用户未登录时,应用程序将以默认主题启动。登录后我可以识别用户并且必须更改主题。但是我该怎么做。登录过程不在 android 项目中,从那里我无法访问 MainActivity。

如何设置新主题并重新创建应用程序?

非常感谢您的帮助。

更新


登录方法目前在 MC.Core (Shared) (.NET Standard 2.0) 库中,MainActivity 在 MC.Android 库中。所以有一个插件,您可以通过它访问项目的实际事件,但我不能使用它,因为它支持 .Net 标准。

而且我不确定我是否可以通过两个项目订阅一个事件。如果这是可能的,我该怎么做?

我最后的解决方案是将登录方法从我的核心项目移至 Android 项目。但在这种情况下,我必须为每个平台实现它。

最佳答案

要从网络标准项目调用 MainActivity 中的方法,您需要将对 MainActivity 的引用传递给标准项目。执行此操作的最佳方法是传递对共享网络标准项目 App 构造函数的引用,该构造函数从 MainActivity 调用。当然,你不能在你的 App 构造函数中声明一个 MainActivity 类型的参数,因为你的网络标准项目不能引用 Android 项目,而且因为,如果你将来要实现你的应用程序的 iOS 和/或 UWP 版本,你需要一个所有这些不同项目之间的通用类型。

因此,您必须在您的网络标准项目中定义一个接口(interface):

public interface IThemeChanger
{
void ApplyTheme(string newTheme);
}

然后,在Android项目中,让你的MainActivity实现这个接口(interface):

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IThemeChanger
{
public void ApplyTheme(string newTheme)
{
if (newTheme?.ToLower() == "dark")
{
SetTheme(Resource.Style.Base_Theme_AppCompat);
}
else
{
SetTheme(Resource.Style.Base_Theme_AppCompat_Light);
}
}

并让它在应用类的构造函数中传递对自身的引用:

protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;

base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App(this));
}

然后,在网络标准 App 类中,更改构造函数,使其接受 IThemeChanger 类型的参数,并将对它的引用存储在私有(private)或公共(public)字段中(取决于您是否需要从 App 外部访问它类):

    public readonly IThemeChanger ThemeChanger;
public App(IThemeChanger themeChanger)
{
InitializeComponent();
this.ThemeChanger = themeChanger;
MainPage = new MainPage();
}

然后,在你的登录页面,用户登录成功后,相应地更改主题,例如:

((App.Current) as App).ThemeChanger.ApplyTheme("Dark");

如果您不直接实例化您的 App 类,而是使用依赖项注入(inject)容器,则将 MainActivity 的当前实例注册为您的容器的 IThemeChanger 接口(interface)的实现者,并在您的 ViewModel 的构造函数中简单地请求一个 IThemeChanger 实例。当然,语法因您使用的 DI 容器而异,这里是 Caliburn.Micro SimpleContainer 的示例:

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IThemeChanger
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;

base.OnCreate(savedInstanceState);

var container = IoC.Get<SimpleContainer>();
if (container.HasHandler<IThemeChanger>())
{
container.UnregisterHandler<IThemeChanger>();
}
container.Instance<IThemeChanger>(this);

global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(container.GetInstance<App>());
}

在这种情况下,请注意,在应用恢复期间可能会创建一个新的 MainActivity 实例,因此您需要检查该接口(interface)的潜在先前注册并将其注销。

在您的 ViewModel 中:

public class LoginViewmModel{
private readonly IThemeChanger themeChanger;

public LoginViewModel(IThemeChanger themeChanger){
this.themeChanger = themChanger;
}

private void ApplyTheme{
themeChanger.ApplyTheme("Dark");
}
}

关于xamarin - Android 以编程方式更改主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52117646/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com