2012-09-27 20 views
16

En mi aplicación, que tienen un Spinner se llena de una enumeración:¿Cómo acceder a las cadenas de recursos de ToString de enum en Android?

ArrayAdapter<myEnum> enumAdapter = new ArrayAdapter<Stroke> (parentActivity.getApplicationContext(), R.layout.simple_spinner_item, myEnum.values()); 
enumAdapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item); 
enumSpinner.setAdapter(strokeAdapter); 

Este utiliza un reemplazo del método de la enumeración toString() para obtener un nombre descriptivo para los valores de enumeración para mostrar en el Spinner. Actualmente, mi enumeración tiene cadenas codificadas para los nombres descriptivos, pero me gustaría moverlas al strings.xml para apoyar la localización.

Sin embargo, toString no tiene acceso a Context, por lo que no estoy seguro de cómo resolver los identificadores de recursos.

¿Hay alguna forma de obtener cadenas localizadas en el método toString() de una enumeración?

+2

Una enumeración es sólo una abreviatura de una clase. Crea una clase singleton que hace el trabajo. El método toString() puede acceder a lo que quiera. – Simon

+0

¿Por qué usar la cadena actual? La mayoría de 'View.setText()' por ejemplo también puede tomar un resourceID. De forma similar, los creadores de opciones pueden tomar matrices de ID de recursos en lugar de matrices de cadenas. – ccpizza

Respuesta

20

Si entiendo correctamente, la pregunta real aquí es cómo conseguir un Context de su enum , para que pueda llamar al Context.getString() para obtener versiones localizadas de las cadenas que necesita.

Un enfoque, sería establecer una variable de miembro estático de tipo Context en el método onCreate() de su aplicación, que se describe en this answer. La idea aquí es que cada vez que su aplicación se crea o se recrea, usted se aferrará al contexto de la aplicación en una variable que es fácil de acceder.

Luego, ingrese la ID del recurso en el constructor de sus valores enum, y use el contexto en su método toString().

Por ejemplo:.

public enum Example { 
    HELLO(R.string.hello), 
    WORLD(R.string.world); 

    private int mResourceId; 

    private Example(int id) { 
     mResourceId = id; 
    } 

    @Override 
    public String toString() { 
     return App.getContext().getString(mResourceId); 
    } 
} 
+0

Sí, el acceso al Contexto me desconcertaba. ¡Gracias! – fortyCakes

+3

Tengo una solución que hace innecesario el campo en enumeración: http://stackoverflow.com/a/29625457/1891118 –

1

No estoy 100% seguro de que entiendo lo que está preguntando.

¿Hay alguna forma de obtener cadenas localizadas en el método toString() de una enumeración?

Por supuesto que puede @Override el método toString() interior de su myEnum permite cambiar la forma en que se muestra:

public enum myEnum { 
    ONE("1"), 
    TWO("2"); 
    private String pretty; 
    private myEnum(String pretty) { 
     this.pretty = pretty; 
    } 
    @Override 
    public String toString() { 
     // you can localise this string somehow here 
     return pretty; 
    } 
} 
+1

Estoy buscando una forma de utilizar los id. De Android R.string.foo para buscar una versión traducida de la cadena dentro del método toString, donde normalmente no tiene acceso a un contexto de aplicación. – fortyCakes

4

@ Override public String toString() { retorno App.getContext() getString (id); }

Es importante que su doesnt clase de enumeración tiene ningún vínculo con su actividad ya que si desea utilizar en otra aplicación, entonces no será capaz de si su referencia a un contexto estático.

Así que una forma mejor sería devolver la identificación del recurso de la cadena a la actividad y luego dejar que la actividad tome la cadena usando la identificación de su.

lo tanto de su clase de enumeración que tendría un método buscando algo similar a esto:

public int getResourceId() 
    { 
    return resourceId; 
    } 

Luego, en su actividad me construir una lista que contiene un ArrayList:

final List<String> enumList = new ArrayList<String>(); 
for (final MyEnum status : MyEnum.values()) 
{ 
    enumList.add(getString(status.getResourceId())); 
} 

A continuación, puede usar enumList con su ArrayAdapter, Bingo :)

Así que ahora no tiene vínculos con la clase enum, y si está construyendo otra aplicación que necesita usar la misma enumeración cl Culo tu calidad fácilmente hazlo.

+0

En mi humilde opinión, esto es mejor ya que evita un contexto estático en la aplicación. – James

2

Usar la aplicación estática es siempre una mala práctica, porque no solo rompe la ejecución instantánea, sino que también está en contra del principio de desacoplamiento, por lo que dificulta la implementación de la modularización. Sin mencionar que Android realmente admite múltiples aplicaciones en un solo proceso.

Por esta razón, sugiero definir una clase interna para la enumeración como entradas de su adaptador.

enum Example { 
    A(R.string.label_a), 
    B(R.string.label_b); 

    Example(@StringRes int label) { mLabel = label; } 
    private @StringRes int mLabel; 

    class Entry { 
     private final Context mContext; 
     Entry(final Context context) { mContext = context; } 
     @Override public String toString() { return mContext.getString(mLabel); } 
    } 
} 

A continuación, cree una matriz de Ejemplo.Entrada para el adaptador.

Arrays.stream(Example.values()).map(item -> item.new Entry(context)).toArray(Example.Entry[]::new) 
Cuestiones relacionadas