Android: come posso ottenere la stringa dalle risorse usando il suo nome?


553

Vorrei avere 2 lingue per l'interfaccia utente e valori stringa separati per loro nel mio file di risorse res\values\strings.xml:

<string name="tab_Books_en">Books</string>
<string name="tab_Quotes_en">Quotes</string>
<string name="tab_Questions_en">Questions</string>
<string name="tab_Notes_en">Notes</string>
<string name="tab_Bookmarks_en">Bookmarks</string>

<string name="tab_Books_ru">Книги</string>
<string name="tab_Quotes_ru">Цитаты</string>
<string name="tab_Questions_ru">Вопросы</string>
<string name="tab_Notes_ru">Заметки</string>
<string name="tab_Bookmarks_ru">Закладки</string>

Ora devo recuperare questi valori in modo dinamico nella mia app:

spec.setContent(R.id.tabPage1);
String pack = getPackageName();
String id = "tab_Books_" + Central.lang;
int i = Central.Res.getIdentifier(id, "string", pack);
String str = Central.Res.getString(i);

Il mio problema è quello i = 0.

Perché non funziona nel mio caso?


1
Sei sicuro che Central.lang sia o eno ru?
K-ballo,

1
Ulteriori informazioni sono necessarie per ispezionare il tuo codice. qual è lo stato di ogni var prima di ottenerlo? Ad ogni modo, dovresti usare il supporto di localizzazione predefinito in Android per semplificare le cose.
Alin,

Risposte:


1069

Il collegamento a cui ti riferisci sembra funzionare con le stringhe generate in fase di esecuzione. Le stringhe da strings.xml non vengono create in fase di esecuzione. Puoi ottenerli tramite

String mystring = getResources().getString(R.string.mystring);

getResources()è un metodo di Contextclasse. Se ti trovi in ​​a Activityo a Service(che estende il contesto) puoi usarlo come in questo frammento.

Si noti inoltre che l'intera dipendenza dalla lingua può essere gestita dal framework Android . Crea semplicemente cartelle diverse per ogni lingua. Se l'inglese è la lingua predefinita, inserisci semplicemente le stringhe inglesi res/values/strings.xml. Quindi crea una nuova cartella values-rue inserisci le stringhe russe con nomi identici res/values-ru/strings.xml. Da questo punto su Android seleziona quello corretto a seconda delle impostazioni locali del dispositivo, sia quando chiami che quando fai getString()riferimento a stringhe in XML tramite @string/mystring. Quelli da res/values/strings.xmlsono quelli di fallback, se non si dispone di una cartella che copre le impostazioni internazionali degli utenti, questa verrà utilizzata come valori predefiniti.

Vedere Localizzazione e fornitura di risorse per ulteriori informazioni.


23
Se ti trovi in android.support.v4.app.Fragment, puoi semplicemente chiamare getString(R.string.mystring)direttamente.
JaKXz,

3
Stavo solo wodering. Perché è fatto (da Google) in un modo così complicato? Prima ottieni l'ID numerico di mystring (dall'oggetto R) e poi ottieni la stringa da quell'ID? E dove risiede effettivamente la coppia "ID-of-mystring => actualValue"? Per quanto ne so mystring => ID-of-mystring è in R.java, ma è così :)
Lukáš Řádek

2
assicurati che "R" sia la R del tuo progetto, non l'androide di default R.
ralphgabb,

2
Questa potrebbe essere la risposta che era necessaria ma non era quella richiesta! Per accedere dinamicamente a una risorsa stringa per nome, vedere la risposta di @leonvian ... che dovrebbe essere quella accettata IMO
Chris Hatton,

321

Ho lo stesso problema. Ma questo codice qui sotto funziona per me: Verifica se il nome del pacchetto è corretto. Devi fare riferimento per il pacchetto radice della tua applicazione Android.

private String getStringResourceByName(String aString) {
      String packageName = getPackageName();
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }

9
Nel caso in cui qualcuno abbia una buona ragione per farlo (ad esempio, i file di dati contengono una stringa personalizzata che decide quale stringa di risorse deve essere visualizzata o se questa stringa viene recuperata da Internet), quindi vorrei sottolineare che questa soluzione è quella corretta. Soprattutto correggere la parte in cui si trova il tipo di risorsa stringe non strings. Perché è logico (come il resto di Android). Quindi, grazie per quello (e altro), @leonvian. :-)
Ivan Vučica,

2
@Sameer per ottenere un array da Strings basta usare: res.getStringArray (R.array.planets_array); Dai un'occhiata a questo link ufficiale: developer.android.com/guide/topics/resources/…
leonvian

3
Freddo. Per sbarazzarsi di una dichiarazione di metodo separato, questo può essere "semplificato" in modo tale: String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));.
Neurotrasmettitore

80

Non solo dalle attività:

    public static String getStringByIdName(Context context, String idName) {
        Resources res = context.getResources();
        return res.getString(res.getIdentifier(idName, "string", context.getPackageName()));
    }

ha funzionato alla grande grazie
Mosa

39
getResources().getString(getResources().getIdentifier("propertyName", "string", getPackageName()))

26

Vorrei aggiungere qualcosa alla soluzione di leonvian, quindi se per caso la stringa non viene trovata tra le risorse (valore di ritorno 0, che non è un codice di risorsa valido), la funzione potrebbe restituire qualcosa:

private String getStringResourceByName(String aString) {
    String packageName = getPackageName();
    int resId = getResources()
            .getIdentifier(aString, "string", packageName);
    if (resId == 0) {
        return aString;
    } else {
        return getString(resId);
    }
}

15

Il miglior approccio

App.getRes().getString(R.string.some_id)

Funzionerà ovunque (Utilità, anche modelli).

Ho letto tutte le risposte, tutte le risposte possono fare il tuo lavoro.

  • È possibile utilizzare getString(R.string.some_string_id)in entrambi Activityo Fragment.
  • Puoi usare Context.getString(R.string.some_string_id)dove non hai accesso diretto al getString()metodo. Come Dialog.

Problema

Quando non hai Contextaccesso , come un metodo nella tua Utilclasse.

Assumi il metodo seguente senza contesto.

public void someMethod(){
    ...
    // can't use getResource() or getString() without Context.
}

Ora passerai Contextcome parametro in questo metodo e utilizzeraigetString().

public void someMethod(Context context){
    ...
    context.getString(R.string.some_id);
}

Quello che faccio è

public void someMethod(){
    ...
    App.getAppResources().getString(R.string.some_id)
}

Che cosa? È molto semplice da usare ovunque nella tua app!

Quindi ecco una soluzione con la quale puoi accedere alle risorse da qualsiasi luogo simile Util class.

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static Resources resources;

    @Override
    public void onCreate() {
        super.onCreate();

        resources = getResources();
    }

    public static Resources getAppResources() {
        return resources;
    }

}

Aggiungi il campo del nome al tuo manifest.xml <applicationtag.

<application
        android:name=".App"
        ...
        >
        ...
    </application>

Ora sei a posto. Utilizza App.getAppResources().getString(R.string.some_id)ovunque in app.


+1 soluzione semplice e pulita. Notare una cattiva ortografia getResourses, getResourcescauserebbe l'override. Anche il modello singleton sembra superfluo, forse potrebbe essere saltato. Qualche problema di memoria perde con questa soluzione?
Xarvalus,

@Xarvalus Questo fa perdere la memoria?
Khemraj,

nella mia app tutto bene :) mi chiedevo solo se qualcuno avesse qualche problema con esso. Lo farò sapere se incontro qualche insidia.
Xarvalus,

1
La perdita di memoria di @Xarvalus di solito si verifica nel luogo in cui viene utilizzata una variabile anche se la classe genitore viene distrutta. Come in Attività, Frammenti. Non penso che accadrà in questo caso.
Khemraj,


14

Un modo semplice per ottenere la stringa di risorse dalla stringa in un TextView. Qui resourceName è il nome della risorsa

int resID = getResources().getIdentifier(resourceName, "string", getPackageName());
textview.setText(resID);

7

Se non si dispone di un riferimento Attività, è possibile utilizzare il contesto in questo modo:

getContext().getString(R.string.your_string_name);

4

Esiste anche una serie di stringhe Android predefinite come "Ok", "Annulla" e molte altre, quindi non è necessario dichiarare tutto. Sono disponibili semplicemente tramite:

getString(android.R.string.ok)

(In questo caso, stringa "Ok"). A proposito ci sono anche altre risorse Android disponibili come ad esempio immagini icone ecc.


2

String myString = getString (R.string.mystring);

modo semplice


1

Puoi provare questo in un'attività:

getResources().getString(R.string.your string name);

In altre situazioni come i frammenti, ... usa

getContext().getResources().getString(R.string.your string name);

0

Per sicurezza, dovresti aggiungere: mContext.getResources (). GetString (R.string.your_string);

mContext può essere: context in onAttach () di Fragment o this of Activity.


0

Se non lo ottieni all'interno di un'attività o fragmnet, allora:

getContext().getResources().getString(R.string.string_name);

Se si desidera ottenerlo da una classe esterna all'attività o al frammento in cui non si ha il contesto dell'attività, utilizzare il contesto dell'applicazione:

getApplicationContext().getResources().getString(R.string.string_name);

0
R.string.<string_name>

Usa quella linea direttamente nel tuo file java. Mantienilo semplice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.