wake-up-neo.net

Wie man das aktuelle Theme zur Laufzeit in Android

Ich habe eine PreferenceActivity erstellt, mit der der Benutzer das Thema auswählen kann, das er auf die gesamte Anwendung anwenden möchte.

Wenn der Benutzer ein Thema auswählt, wird dieser Code ausgeführt:

if (...) {
    getApplication().setTheme(R.style.BlackTheme);
} else {
    getApplication().setTheme(R.style.LightTheme);
}

Aber obwohl ich mit dem Debugger überprüft habe, dass der Code ausgeführt wird, kann ich keine Änderung in der Benutzeroberfläche feststellen.

Themen sind in res/values/styles.xml Definiert, und Eclipse zeigt keinen Fehler an.

<resources>
    <style name="LightTheme" parent="@Android:style/Theme.Light">
    </style>

    <style name="BlackTheme" parent="@Android:style/Theme.Black">
    </style>    
</resources>

Haben Sie eine Vorstellung davon, was passieren könnte und wie dies behoben werden kann? Soll ich setTheme an einer bestimmten Stelle im Code aufrufen? Meine Bewerbung besteht aus mehreren Aktivitäten, wenn das hilft.

140
Guido

Ich möchte auch die Methode sehen, bei der Sie einmal für alle Ihre Aktivitäten festlegen. Aber soweit ich weiß, müssen Sie jede Aktivität einstellen, bevor Sie Ansichten anzeigen können.

Als Referenz überprüfen Sie dies:

http://www.anddev.org/applying_a_theme_to_your_application-t817.html

Bearbeiten (aus diesem Forum kopiert):

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

Wenn Sie das Thema einer bereits vorhandenen Aktivität ändern möchten, rufen Sie recreate() nach setTheme() auf.

Hinweis: Rufen Sie recreate nicht auf, wenn Sie das Thema in onCreate() ändern, um eine Endlosschleife zu vermeiden.

57
TPReal

recreate() (wie von TPReal erwähnt) startet nur die aktuelle Aktivität neu, die vorherigen Aktivitäten befinden sich jedoch noch im Hintergrund und das Thema wird nicht auf sie angewendet.

Eine andere Lösung für dieses Problem besteht darin, den Task-Stack wie folgt vollständig neu zu erstellen:

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

BEARBEITEN:

Fügen Sie einfach den obigen Code ein, nachdem Sie das Thema auf der Benutzeroberfläche oder an einer anderen Stelle geändert haben. Alle Ihre Aktivitäten sollten die Methode setTheme() haben, die vor onCreate() aufgerufen wurde, wahrscheinlich in einer übergeordneten Aktivität. Es ist auch eine normale Vorgehensweise, das in SharedPreferences ausgewählte Thema zu speichern, es zu lesen und dann mit der setTheme() -Methode festzulegen.

21
Yuriy Yunikov

ich habe das gleiche Problem, aber ich habe die Lösung gefunden.

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

Ich hatte ein ähnliches Problem und habe es auf diese Weise gelöst.

@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

}

dieser Code dient zum erneuten Erstellen des Aktivitätssparbündels und zum Ändern des Themas. Sie müssen Ihren eigenen onSaveInstanceState (Bundle outState) schreiben. Ab API-11 können Sie stattdessen die Methode recreate () verwenden

Bundle temp_bundle = new Bundle();
onSaveInstanceState(temp_bundle);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("bundle", temp_bundle);
startActivity(intent);
finish();
9

Wir müssen das Thema einstellen, bevor wir 'super.onCreate ()' und 'setContentView ( ) ' Methode.

Schauen Sie sich diesen Link an, um ein neues Thema zur Laufzeit auf die gesamte Anwendung anzuwenden.

9
Lalit Sharma

Anstatt

getApplication().setTheme(R.style.BlackTheme);

verwenden

setTheme(R.style.BlackTheme);

Mein Code: in onCreate () Methode:

super.onCreate(savedInstanceState);

if(someExpression) {
    setTheme(R.style.OneTheme);
} else {
    setTheme(R.style.AnotherTheme);
}

setContentView(R.layout.activity_some_layout);

Irgendwo (zum Beispiel auf einen Knopfdruck):

YourActivity.this.recreate();

Sie müssen die Aktivität andernfalls neu erstellen - Änderungen werden nicht vorgenommen

4

Ich weiß, dass ich zu spät komme, aber ich möchte hier eine Lösung posten: Überprüfen Sie den vollständigen Quellcode hier . Dies ist der Code, den ich beim Ändern des Themas mithilfe von Einstellungen verwendet habe.

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

So arbeite für mich:

  @Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(GApplication.getInstance().getTheme());
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
}

Dann möchten Sie ein neues Thema ändern:

GApplication.getInstance().setTheme(R.style.LightTheme);
recreate();
2
duongnx

Dies ist, was ich für Material Design erstellt habe. Möge es Ihnen helfen.

Schauen Sie nach MultipleThemeMaterialDesign

Sie können die Aktivität beenden und anschließend neu erstellen. Auf diese Weise wird Ihre Aktivität erneut erstellt und alle Ansichten werden mit dem neuen Thema erstellt.

1
Sumit Dhaniya

Rufen Sie nach setTheme () SetContentView (Resource.Layout.Main) auf.

0

Das hatte für mich keine Auswirkung:

public void changeTheme(int newTheme) {
    setTheme(newTheme);
    recreate();
}

Aber das hat funktioniert:

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