web-dev-qa-db-ja.com

Androidで実行時に現在のテーマを変更する方法

ユーザーがアプリケーション全体に適用するテーマを選択できるようにする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を呼び出す必要がありますか?それが役立つ場合、私のアプリケーションはいくつかのアクティビティで構成されています。

140
Guido

すべてのアクティビティに対して一度設定する方法も見たいです。しかし、私が知る限り、ビューを表示する前に各アクティビティを設定する必要があります。

参考のためにこれを確認してください:

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);
}
84
Pentium10

既存のアクティビティのテーマを変更する場合は、 recreate() の後に setTheme() を呼び出します。

注:無限ループを避けるために、onCreate()でテーマを変更する場合は、recreateを呼び出さないでください。

57
TPReal

recreate()TPReal で述べたように)は現在のアクティビティのみを再開しますが、前のアクティビティはバックスタックに残り、テーマはそれらに適用されません。

したがって、この問題の別の解決策は、次のようにタスクスタックを完全に再作成することです。

    TaskStackBuilder.create(getActivity())
            .addNextIntent(new Intent(getActivity(), MainActivity.class))
            .addNextIntent(getActivity().getIntent())
            .startActivities();

編集:

UIまたは他の場所でテーマの変更を実行した後、上記のコードを配置するだけです。すべてのアクティビティには、おそらくいくつかの親アクティビティで、setTheme()の前に呼び出されるメソッドonCreate()が必要です。また、SharedPreferencesで選択したテーマを保存し、読み取ってからsetTheme()メソッドを使用して設定することも通常の方法です。

21
Yuriy Yunikov

私は同じ問題を抱えていましたが、解決策を見つけました。

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);
    }
}
17
Unknown

同様の問題があり、このようにして解決しました。

@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();
9

呼び出す前にテーマを設定する必要があります 'super.onCreate()'および 'setContentView()'メソッド。

これを確認してください link 実行時にアプリケーション全体に新しいテーマを適用します。

9
Lalit Sharma

の代わりに

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();

それ以外の場合は、アクティビティを再作成する必要があります-変​​更は発生しません

4

私は遅れていることを知っていますが、ここに解決策を投稿したいと思います:完全なソースコードを確認してください 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);
}
2
dondondon

この方法は私のために働く:

  @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();
2
duongnx

これはマテリアルデザインのために作成したものです。お役に立てば幸いです。

MultipleThemeMaterialDesign をご覧ください

この方法でアクティビティを終了して再作成すると、アクティビティが再び作成され、すべてのビューが新しいテーマで作成されます。

1
Sumit Dhaniya

SetTheme()の後にSetContentView(Resource.Layout.Main)を呼び出します。

0

これは私には効果がありませんでした:

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();
}
0
arlomedia