76 votes

Android : Comment obtenir l'ID de ressource du thème en cours ?

Dans Android, vous pouvez obtenir le thème actuel d'une activité en Resource.Theme objet de getTheme() . En outre, vous pouvez définir le thème sur un autre via l'ID de ressource de cet autre thème, comme dans setTheme(R.style.Theme_MyTheme) .

Mais comment savoir si cela en vaut la peine, si le thème actuel est déjà celui que je voudrais définir ? Je cherche quelque chose comme getTheme().getResourceId() , afin d'écrire quelque chose comme :

 protected void onResume() {
    int newThemeId = loadNewTheme();
    if (newThemeId != getTheme().getResourceId()) { // !!!! How to do this?
        setTheme(newThemeId);
        // and rebuild the gui, which is expensive
    }
}

Des idées?

49voto

marmor Points 4559

J'ai trouvé un moyen de résoudre l'exigence sans obtenir l'identifiant de la ressource.

J'ajoute un élément à chacun de mes thèmes avec le nom de la chaîne :

 <item name="themeName">dark</item>

Et dans le code je vérifie le nom comme ceci :

 TypedValue outValue = new TypedValue();
getTheme().resolveAttribute(R.attr.themeName, outValue, true);
if ("dark".equals(outValue.string)) {
   ...
}

13voto

Karakuri Points 11241

Il existe un moyen de le faire via la réflexion. Mettez ceci dans votre activité :

 int themeResId = 0;
try {
    Class<?> clazz = ContextThemeWrapper.class;
    Method method = clazz.getMethod("getThemeResId");
    method.setAccessible(true);
    themeResId = (Integer) method.invoke(this);
} catch (NoSuchMethodException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
} catch (IllegalAccessException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
} catch (IllegalArgumentException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
} catch (InvocationTargetException e) {
    Log.e(TAG, "Failed to get theme resource ID", e);
}
// use themeResId ...

[Insérer ici la clause de non-responsabilité concernant les API non publiques]

9voto

Dem0n13 Points 340

Selon les sources, Activity.setTheme est appelé avant Activity.onCreate, vous pouvez donc enregistrer le themeId lorsque Android le définit :

 public class MainActivity extends Activity {
    private int themeId;

    @Override
    public void setTheme(int themeId) {
        super.setTheme(themeId);
        this.themeId = themeId;
    }

    public int getThemeId() {
        return themeId;
    }
}

2voto

Si vous avez spécifié android:theme="@style/SomeTheme" dans l' <activity/> de votre manifeste, vous pouvez obtenir l'ID de ressource du thème de l'activité comme ceci :

 int themeResId;
try {
    PackageManager packageManager = getPackageManager();
    //ActivityInfo activityInfo = packageManager.getActivityInfo(getCallingActivity(), PackageManager.GET_META_DATA);
    ActivityInfo activityInfo = packageManager.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
    themeResId = activityInfo.theme;
}
catch(PackageManager.NameNotFoundException e) {
    Log.e(LOG_TAG, "Could not get themeResId for activity", e);
    themeResId = -1;
}

N'oubliez pas, si vous allez ensuite appeler setTheme(themeResId) dans la méthode onCreate() de votre activité, vous devez le faire avant d'appeler setContentView(...) .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X