2011-09-01 25 views
45

En Android, puede obtener el tema actual de una actividad como un objeto Resource.Theme de getTheme(). Además, puede establecer el tema en uno diferente a través de la identificación de recursos de ese otro tema, como en setTheme(R.style.Theme_MyTheme).Android: ¿Cómo obtener el ID del recurso del tema actual?

Pero, ¿cómo puedo saber si vale la pena, si el tema actual ya es el que me gustaría establecer? Busco algo así como getTheme().getResourceId(), con el fin de escribir algo como:

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

¿Alguna idea?

+0

No creo que el ID de recurso sea un atributo de la clase Theme. El tema puede crearse a partir del archivo reource xml, pero luego se pierde la referencia a la ID. El tema en sí podría cambiarse, y entonces no tendría ningún significado que se vincule con una determinada ID de recurso. Aún más, el tema podría crearse sobre la marcha en código. Tendrá que hacer un seguimiento de qué identificador de reutilización se utilizó para el tema actual usted mismo. – Anderson

+0

Esta respuesta te ayudará. Consulte este http://stackoverflow.com/a/26302184/4639479 –

Respuesta

34

bien aquí es una pieza del rompecabezas: podemos obtener el valor por defecto tema , tal como se establece en el AndroidManifest.xml, como context.getApplicationInfo().theme para el tema establecido a nivel de aplicación, y desde dentro de una actividad, como getPackageManager().getActivityInfo(getComponentName(), 0).theme para esa actividad.

Supongo que eso nos da un punto de partida para hacer nuestro propio contenedor para un getTheme() personalizado y setTheme().

Todavía se siente como trabajar en torno en lugar de con la API. Así que dejaré la pregunta abierta para ver si a alguien se le ocurre una mejor idea.

+0

Tiene la misma sensación aquí sobre esto y +1 para encontrarlo. –

+12

Hay un método 'getThemeResId()' en 'Context' pero desafortunadamente no es público :-( –

27

Encontré una manera de resolver el requisito sin obtener la identificación del recurso.

estoy añadiendo un elemento para cada uno de mis temas con el nombre de la cadena:

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

Y en el código verifico el nombre de este modo:

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

Esa es una idea realmente creativa. ¡Gracias! – LoungeKatt

7

Hay una forma de hacer esto a través de la reflexión. Poner esto en su actividad:

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 ... 

[Inserte aquí descargo de responsabilidad con respecto a las API no públicas]

+0

Está funcionando bien. –

3

Según sources Activity.setTheme se llama antes de Activity.onCreate, lo que puede ahorrar el themeId cuando androide puso :

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; 
    } 
} 
Cuestiones relacionadas