Чтобы вызвать метод в вашей MainActivity из стандартного проекта сети, вам нужно передать ссылку на вашу MainActivity в стандартный проект. Лучший способ сделать это - передать ссылку на конструктор приложения стандартного общего сетевого проекта, который вызывается из MainActivity. Конечно, вы не можете объявить параметр в конструкторе вашего приложения типа MainActivity, потому что ваш стандартный сетевой проект не может ссылаться на проект Android, и потому что, если вы в будущем внедрите версию своего приложения для iOS и / или UWP, вам потребуется общий тип между всеми этими различными проектами.
Итак, вы должны определить интерфейс в вашем сетевом стандартном проекте:
public interface IThemeChanger
{
void ApplyTheme(string newTheme);
}
Затем в проекте Android заставьте MainActivity реализовать этот интерфейс:
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, и сохраните ссылку на него в закрытом или открытом поле (в зависимости от того, нужен ли вам доступ к нему из-за пределов приложения). класс):
public readonly IThemeChanger ThemeChanger;
public App(IThemeChanger themeChanger)
{
InitializeComponent();
this.ThemeChanger = themeChanger;
MainPage = new MainPage();
}
Затем на странице входа в систему после успешного входа пользователя измените тему соответствующим образом, например:
((App.Current) as App).ThemeChanger.ApplyTheme("Dark");
Если вы не создаете экземпляр класса App напрямую, а используете контейнер для внедрения зависимостей, зарегистрируйте текущий экземпляр MainActivity в качестве реализации интерфейса IThemeChanger в своем контейнере и просто запросите экземпляр IThemeChanger в конструкторе вашей ViewModel. Конечно, синтаксис зависит от того, какой контейнер 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 может быть создан во время возобновления работы приложения, поэтому вам необходимо проверить наличие потенциальной предыдущей регистрации интерфейса и отменить его регистрацию.
В вашей ViewModel:
public class LoginViewmModel{
private readonly IThemeChanger themeChanger;
public LoginViewModel(IThemeChanger themeChanger){
this.themeChanger = themChanger;
}
private void ApplyTheme{
themeChanger.ApplyTheme("Dark");
}
}