ユーザーがアプリケーション全体に適用するテーマを選択できるようにするPreferenceActivityを作成しました。
ユーザーがテーマを選択すると、次のコードが実行されます。
if (...) {
getApplication().setTheme(R.style.BlackTheme);
} else {
getApplication().setTheme(R.style.LightTheme);
}
しかし、コードが実行されていることをデバッガーで確認しましたが、ユーザーインターフェイスに変更はありません。
テーマはres/values/styles.xml
で定義されており、Eclipseはエラーを表示しません。
<resources>
<style name="LightTheme" parent="@Android:style/Theme.Light">
</style>
<style name="BlackTheme" parent="@Android:style/Theme.Black">
</style>
</resources>
何が起こる可能性があり、それを修正する方法についてのアイデアはありますか?コードの特別なポイントでsetTheme
を呼び出す必要がありますか?それが役立つ場合、私のアプリケーションはいくつかのアクティビティで構成されています。
すべてのアクティビティに対して一度設定する方法も見たいです。しかし、私が知る限り、ビューを表示する前に各アクティビティを設定する必要があります。
参考のためにこれを確認してください:
http://www.anddev.org/applying_a_theme_to_your_application-t817.html
編集(そのフォーラムからコピー):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Call setTheme before creation of any(!) View.
setTheme(Android.R.style.Theme_Dark);
// ...
setContentView(R.layout.main);
}
既存のアクティビティのテーマを変更する場合は、 recreate()
の後に setTheme()
を呼び出します。
注:無限ループを避けるために、onCreate()
でテーマを変更する場合は、recreateを呼び出さないでください。
recreate()
( TPReal で述べたように)は現在のアクティビティのみを再開しますが、前のアクティビティはバックスタックに残り、テーマはそれらに適用されません。
したがって、この問題の別の解決策は、次のようにタスクスタックを完全に再作成することです。
TaskStackBuilder.create(getActivity())
.addNextIntent(new Intent(getActivity(), MainActivity.class))
.addNextIntent(getActivity().getIntent())
.startActivities();
編集:
UIまたは他の場所でテーマの変更を実行した後、上記のコードを配置するだけです。すべてのアクティビティには、おそらくいくつかの親アクティビティで、setTheme()
の前に呼び出されるメソッドonCreate()
が必要です。また、SharedPreferences
で選択したテーマを保存し、読み取ってからsetTheme()
メソッドを使用して設定することも通常の方法です。
私は同じ問題を抱えていましたが、解決策を見つけました。
public class EditTextSmartPhoneActivity extends Activity implements DialogInterface.OnClickListener
{
public final static int CREATE_DIALOG = -1;
public final static int THEME_HOLO_LIGHT = 0;
public final static int THEME_BLACK = 1;
int position;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
position = getIntent().getIntExtra("position", -1);
switch(position)
{
case CREATE_DIALOG:
createDialog();
break;
case THEME_HOLO_LIGHT:
setTheme(Android.R.style.Theme_Holo_Light);
break;
case THEME_BLACK:
setTheme(Android.R.style.Theme_Black);
break;
default:
}
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
private void createDialog()
{
/** Options for user to select*/
String choose[] = {"Theme_Holo_Light","Theme_Black"};
AlertDialog.Builder b = new AlertDialog.Builder(this);
/** Setting a title for the window */
b.setTitle("Choose your Application Theme");
/** Setting items to the alert dialog */
b.setSingleChoiceItems(choose, 0, null);
/** Setting a positive button and its listener */
b.setPositiveButton("OK",this);
/** Setting a positive button and its listener */
b.setNegativeButton("Cancel", null);
/** Creating the alert dialog window using the builder class */
AlertDialog d = b.create();
/** show dialog*/
d.show();
}
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
AlertDialog alert = (AlertDialog)dialog;
int position = alert.getListView().getCheckedItemPosition();
finish();
Intent intent = new Intent(this, EditTextSmartPhoneActivity.class);
intent.putExtra("position", position);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
同様の問題があり、このようにして解決しました。
@Override
public void onCreate(Bundle savedInstanceState) {
if (getIntent().hasExtra("bundle") && savedInstanceState==null){
savedInstanceState = getIntent().getExtras().getBundle("bundle");
}
//add code for theme
switch(theme)
{
case LIGHT:
setTheme(R.style.LightTheme);
break;
case BLACK:
setTheme(R.style.BlackTheme);
break;
default:
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//code
}
このコードは、アクティビティ保存バンドルを再作成し、テーマを変更するためのものです。独自のonSaveInstanceState(Bundle outState);を記述する必要があります。 API-11からは、代わりにメソッドrecreate()を使用できます
Bundle temp_bundle = new Bundle();
onSaveInstanceState(temp_bundle);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("bundle", temp_bundle);
startActivity(intent);
finish();
呼び出す前にテーマを設定する必要があります 'super.onCreate()'および 'setContentView()'メソッド。
これを確認してください link 実行時にアプリケーション全体に新しいテーマを適用します。
の代わりに
getApplication().setTheme(R.style.BlackTheme);
つかいます
setTheme(R.style.BlackTheme);
私のコード:onCreate()メソッド:
super.onCreate(savedInstanceState);
if(someExpression) {
setTheme(R.style.OneTheme);
} else {
setTheme(R.style.AnotherTheme);
}
setContentView(R.layout.activity_some_layout);
どこか(たとえば、ボタンのクリック時):
YourActivity.this.recreate();
それ以外の場合は、アクティビティを再作成する必要があります-変更は発生しません
私は遅れていることを知っていますが、ここに解決策を投稿したいと思います:完全なソースコードを確認してください here 。これは、設定を使用してテーマを変更するときに使用するコードです。
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(this);
String themeName = pref.getString("prefSyncFrequency3", "Theme1");
if (themeName.equals("Africa")) {
setTheme(R.style.AppTheme);
} else if (themeName.equals("Colorful Beach")) {
//Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
setTheme(R.style.beach);
} else if (themeName.equals("Abstract")) {
//Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
setTheme(R.style.abstract2);
} else if (themeName.equals("Default")) {
setTheme(R.style.defaulttheme);
}
この方法は私のために働く:
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(GApplication.getInstance().getTheme());
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
次に、新しいテーマを変更します。
GApplication.getInstance().setTheme(R.style.LightTheme);
recreate();
これはマテリアルデザインのために作成したものです。お役に立てば幸いです。
MultipleThemeMaterialDesign をご覧ください
この方法でアクティビティを終了して再作成すると、アクティビティが再び作成され、すべてのビューが新しいテーマで作成されます。
SetTheme()の後にSetContentView(Resource.Layout.Main)を呼び出します。
これは私には効果がありませんでした:
public void changeTheme(int newTheme) {
setTheme(newTheme);
recreate();
}
しかし、これはうまくいきました:
int theme = R.style.default;
protected void onCreate(Bundle savedInstanceState) {
setTheme(this.theme);
super.onCreate(savedInstanceState);
}
public void changeTheme(int newTheme) {
this.theme = newTheme;
recreate();
}