Как воссоздать предыдущую активность?

У меня есть основное действие (назовем его А) и второе действие (назовем его Б), которое используется для изменения языка приложения. Дело в том, что когда я нажимаю кнопку, чтобы изменить язык, я также вызываю recreate();, а B меняет язык. Пока здесь нормально. Проблема возникает, когда я возвращаюсь к основному действию (A), и он не обновляет язык, потому что он не был воссоздан, поэтому есть ли способ воссоздать A из B, чтобы обновить A?

Я использую этот код для перевода приложения (пример английской версии):

public void btnIngles_onClick(View v)
{
    Locale locale = new Locale("en");
    Locale.setDefault(locale);

    Configuration config = new Configuration();
    config.locale = locale;
    this.getApplicationContext().getResources().updateConfiguration(config, null);
    recreate();
}

person Drumnbass    schedule 17.03.2015    source источник
comment
попробуйте посмотреть Intent и startActivityForResult и передать обновленный язык обратно в результат   -  person chaitanya    schedule 17.03.2015


Ответы (3)


1) Activity B изменяет некоторые глобальные настройки, доступные через SharedPreferences например

2) In Activity A do:

@Override
protected void onResume() {
    super.onResume();
    if(didLanguageChange)
      recreate();
}

Задача решена. Activity A будет вызывать onResume(), так как он переключился в состояние паузы, когда Activity B вышел на передний план.

person Droidman    schedule 17.03.2015
comment
Я сделал это, и он вызывает метод recreate(), но язык активности не меняется.. :( protected void onResume() { super.onResume(); if (idioma.compareTo(Locale.getDefault().getLanguage()) != 0) this.recreate(); } Я проверил, что условие возвращает true и язык изменен, но, как я уже сказал, A не меняет свой язык. - person Drumnbass; 17.03.2015
comment
@Drumnbass, как вы устанавливаете свои тексты? Используете ли вы локализованные строки? - person Droidman; 17.03.2015
comment
Да, на самом деле все приложение переводится (даже контекстные меню на A). Единственное, что не обновляется, это A, даже воссоздающий его, я не знаю, что сказать, это немного странно, но также забавно xD - person Drumnbass; 17.03.2015
comment
@Drumnbass Android использует локаль/язык системы, чтобы определить, какие локализованные строки нужно получить. Как вы меняете язык? Вы вручную меняете локаль? - person Droidman; 17.03.2015
comment
Да, я отредактировал свой пост, чтобы показать вам код, который я использую для смены языка. Может я что-то не так делаю, но приложение все равно переводится, и я думаю, что это не имеет отношения к проблеме. Но вы здесь хозяин, посмотрим, что вы думаете! - person Drumnbass; 17.03.2015
comment
@Drumnbass это не рекомендуется, но в любом случае, проверяете ли вы, что локаль на самом деле изменяется после воссоздания действия A? - person Droidman; 17.03.2015
comment
Я этого не делал (по крайней мере, наблюдая за его значением), но если в этот момент я снова перехожу к B, он переводится - person Drumnbass; 17.03.2015
comment
@Drumnbass добавляет проверку локали в Activity A onCreate() и при необходимости изменяет ее снова. Вам понадобится какой-то другой класс, чтобы предоставить текущую локаль, выбранную пользователем. Явное изменение локали — это своего рода борьба с системой, поэтому приготовьтесь к множественным проверкам. - person Droidman; 17.03.2015
comment
Омг, мне так жаль потраченного времени. Я действительно нашел проблему. Я забыл, что пытался переопределить метод recreate() в действии A (пытаясь вызвать его из B), и, наконец, я оставил его пустым... после удаления этого ошибочного переопределения он отлично работает! Я действительно ценю твою помощь. Спасибо!! :) - person Drumnbass; 17.03.2015

Вам нужно реализовать onActivityResult() в своей деятельности. Эта ссылка содержит дополнительную информацию и должна быть вам очень полезна. В двух словах:

Внутри действия A вам нужно будет создать переменную, используемую в качестве кода запроса, примерно так:

private static final int ACTIVITY_B_REQUEST = 0;

А затем в прослушивателе onClick вашей кнопки вы начнете действие, используя намерение и функцию startActivityForResult():

Intent myIntent = new Intent(ActivityA.this, ActivityB.class);
startActivityForResult(myIntent, ACTIVITY_B_REQUEST);

Это запустит действие B для вас. Всякий раз, когда Activity B завершается, будет вызываться onActivityResult. Вы можете переопределить его и реализовать так, как вам нужно, но это может выглядеть примерно так:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == ACTIVITY_B_REQUEST && resultCode == RESULT_OKAY){
        // Handle this by doing what you need to refresh activity A.
    } else{
        super(requestCode, resultCode, data);
    }   
}
person AdamMc331    schedule 17.03.2015
comment
ИМХО, не будет ли излишним запускать Activity для результата только для того, чтобы проверить, изменились ли какие-то настройки? - person Droidman; 17.03.2015
comment
@Droidman Ты прав, это может быть излишеством. Если им не нужна информация из новой активности, например, на какой язык ее нужно изменить? Это просто показалось мне правильным подходом, потому что они хотели использовать ActivityA для обработки всего, что происходит после завершения ActivityB. - person AdamMc331; 17.03.2015
comment
хорошо, я понимаю вашу точку зрения, хотя я бы предпочел добавить какую-то проверку к OnResume(). Возможно, это просто мой личный подход, так как я всегда реализую вспомогательные классы, которые отслеживают изменения важных настроек и оповещают всех подписчиков, которые заинтересованы в этих изменениях ;) - person Droidman; 17.03.2015
comment
@Droidman определенно. Я все еще учусь, просто пытаюсь получить некоторый опыт, размещая ответы на Android. Они тоже учат меня чему-то новому! Как вы думаете, этот ответ следует удалить? - person AdamMc331; 17.03.2015
comment
конечно нет, так как ваш пример предлагает чистый и рабочий ответ на вопрос. Это действительно редкий случай, когда может существовать только один правильный ответ. Я ни в коем случае не считаю ваш ответ неправильным, просто поделился своим личным мнением - person Droidman; 17.03.2015
comment
@Droidman определенно ценит это, я согласен на 100%. Просто убедился, что это не неправильно. - person AdamMc331; 17.03.2015

Перезапустите приложение:

startActivity(new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent
                .FLAG_ACTIVITY_CLEAR_TOP));
person greywolf82    schedule 17.03.2015