xamarin - Android меняет тему программно - PullRequest
0 голосов
/ 31 августа 2018

У меня мультитенантное приложение, и я должен сменить тему после того, как пользователь войдет в систему.

На данный момент у меня есть то, что, когда пользователь уже вошел в систему и запускает приложение, я вызываю setTheme () для метода MainActivity OnCreate.

Это прекрасно работает, и приложение отображается в правильной теме.

Но когда пользователь не вошел в систему, приложение запустится с темой по умолчанию. После входа в систему я могу узнать пользователя и должен сменить тему. Но как я могу это сделать. Процесс входа не в проект Android, и оттуда у меня нет доступа к MainActivity.

Как мне установить новую тему и воссоздать приложение?

Я очень благодарен за помощь.

UPDATE


Метод входа в данный момент находится в библиотеке MC.Core (Shared) (.NET Standard 2.0), а MainActivity - в библиотеке MC.Android. Так что есть плагин, к которому вы можете получить доступ к фактическим действиям над проектами, но я не могу его использовать, потому что он поддерживает .Net Standard.

И я не уверен, смогу ли я подписаться на мероприятие на два проекта. Если это было бы возможно, как я могу к этому?

Мое последнее решение - перенести метод входа из моего основного проекта в проект Android. Но в этом случае я должен реализовать это для каждой платформы.

1 Ответ

0 голосов
/ 03 сентября 2018

Чтобы вызвать метод в вашей 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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...