複数のテーマをサポートするアプリをいくつか作成しましたが、setTheme()
をsetContentView()
の前に呼び出す必要があるため、ユーザーがテーマを切り替えるときに常にアプリを再起動する必要がありました。
このアプリが見つかるまで大丈夫でした。 2つのテーマをシームレスに切り替えることができ、トランジション/アニメーションも使用できます。
これがどのように実装されたか(およびアニメーションも)のヒントを教えてください。ありがとう!
@Alexander Hanssenの答えは基本的にこれに答えています...なぜそれが受け入れられなかったのかわからない...多分finish()/ startActivity()のせいです。私はそれに投票し、コメントしようとしましたが、できません...
とにかく、私は彼がスタイルの点で説明したことを正確に行います。
<style name="AppThemeLight" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="Android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<!-- Customize your theme here. -->
<item name="Android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<!-- This will set the fade in animation on all your activities by default -->
<style name="WindowAnimationTransition">
<item name="Android:windowEnterAnimation">@Android:anim/fade_in</item>
<item name="Android:windowExitAnimation">@Android:anim/fade_out</item>
</style>
しかし、新しい目的で終了/開始する代わりに:
Intent intent = new Intent(this, <yourclass>.class);
startActivity(intent);
finish();
私はします:
@Override
protected void onCreate(Bundle savedInstanceState) {
// MUST do this before super call or setContentView(...)
// pick which theme DAY or NIGHT from settings
setTheme(someSettings.get(PREFFERED_THEME) ? R.style.AppThemeLight : R.style.AppThemeDark);
super.onCreate(savedInstanceState);
}
// Somewhere in your activity where the button switches the theme
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// decide which theme to use DAY or NIGHT and save it
someSettings.save(PREFFERED_THEME, isDay());
Activity.this.recreate();
}
});
効果はビデオに示されているとおりです...
トランジション/アニメーションは、アクティビティを再開したときにテーマをシームレスに変更します。これを行うには、テーマに「Android:windowanimationStyle」というアイテムを追加し、アクティビティが開始したときのアニメーションの方法を指定するスタイルを参照します。終了します。これにより、アニメーションはそのテーマのすべてのアクティビティに適用されます。
_<style name="AppThemeLight" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="Android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<!-- Customize your theme here. -->
<item name="Android:windowAnimationStyle">@style/WindowAnimationTransition</item>
</style>
<!-- This will set the fade in animation on all your activities by default -->
<style name="WindowAnimationTransition">
<item name="Android:windowEnterAnimation">@Android:anim/fade_in</item>
<item name="Android:windowExitAnimation">@Android:anim/fade_out</item>
</style>
_
次に、テーマを変更する場合は、ボタンをクリックすると次のようになります。
_AppSettings settings = AppSettings.getInstance(this);
settings.set(AppSettings.Key.USE_DARK_THEME,
!settings.getBoolean(AppSettings.Key.USE_DARK_THEME));
Intent intent = new Intent(this, <yourclass>.class);
startActivity(intent);
finish();
_
次に、onCreate
メソッドでsetTheme()
を使用して、次のようにAppSettingsで現在設定されているテーマを適用します。
_AppSettings settings = AppSettings.getInstance(this);
setTheme(settings.getBoolean(AppSettings.Key.USE_DARK_THEME) ? R.style.AppThemeDark : R.style.AppThemeLight);
super.onCreate(savedInstanceState);
setContentView(<yourlayouthere>);
_
参考のためにこのGistを確認してください: https://Gist.github.com/alphamu/f2469c28e17b24114fe5
setTheme()
を呼び出してからsetContentView()
を再度呼び出すことを妨げるものはありません。アプリを少し再構成するだけで、テーマを変更した場合に、View
オブジェクトへの参照を保持している可能性のあるメンバー変数を再初期化する必要があります。