Android: Wie erhalte ich Zeichenfolgen aus Ressourcen unter Verwendung ihres Namens?

553

Ich möchte 2 Sprachen für die Benutzeroberfläche und separate Zeichenfolgenwerte für diese in meiner Ressourcendatei haben 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>

Jetzt muss ich diese Werte dynamisch in meiner App abrufen:

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);

Mein Problem ist das i = 0.

Warum funktioniert es in meinem Fall nicht?

Ivan
quelle
1
Sind Sie sicher, dass Central.lang entweder enoder ist ru?
K-Ballo
1
Weitere Informationen sind erforderlich, um Ihren Code zu überprüfen. Wie ist der Zustand jeder Var, bevor ich i bekomme? Auf jeden Fall sollten Sie die Standardunterstützung für die Lokalisierung in Android verwenden, um die Dinge einfach zu halten.
Alin

Antworten:

1069

Der Link, auf den Sie verweisen, scheint mit zur Laufzeit generierten Zeichenfolgen zu funktionieren. Die Zeichenfolgen aus strings.xml werden zur Laufzeit nicht erstellt. Sie können sie über erhalten

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

getResources()ist eine Methode der ContextKlasse. Wenn Sie sich in einem Activityoder einem Service(das den Kontext erweitert) befinden, können Sie es wie in diesem Snippet verwenden.

Auch beachten Sie, dass die ganze Sprachabhängigkeit Pflege durch den Androiden Rahmen genommen werden kann . Erstellen Sie einfach unterschiedliche Ordner für jede Sprache. Wenn Englisch Ihre Standardsprache ist, geben Sie einfach die englischen Zeichenfolgen ein res/values/strings.xml. Erstellen Sie dann einen neuen Ordner values-ruund fügen Sie die russischen Zeichenfolgen mit identischen Namen ein res/values-ru/strings.xml. Ab diesem Zeitpunkt wählt Android je nach Gebietsschema des Geräts das richtige für Sie aus, entweder beim Aufrufen getString()oder beim Verweisen auf Zeichenfolgen in XML über @string/mystring. Diejenigen von res/values/strings.xmlsind die Fallback-Dateien. Wenn Sie keinen Ordner haben, der das Gebietsschema des Benutzers abdeckt, wird dieser als Standardwerte verwendet.

Weitere Informationen finden Sie unter Lokalisierung und Bereitstellen von Ressourcen .


quelle
23
Wenn Sie in einem sind android.support.v4.app.Fragment, können Sie einfach getString(R.string.mystring)direkt anrufen .
JaKXz
3
Ich habe nur gewimmert. Warum wird es (von Google) so kompliziert gemacht? Zuerst die numerische ID von mystring (vom R-Objekt) abrufen und dann die Zeichenfolge anhand dieser ID abrufen? Und wo befindet sich das Paar "ID-of-mystring => actualValue" tatsächlich? Soweit ich weiß, ist mystring => ID-of-mystring in R.java, aber das ist es :)
Lukáš Řádek
2
Stellen Sie
2
Dies mag die Antwort sein, die benötigt wurde, aber es war nicht die, nach der gefragt wurde! Informationen zum dynamischen Zugriff auf eine Zeichenfolgenressource nach Namen finden Sie in der Antwort von @leonvian ... die als IMO akzeptiert werden sollte
Chris Hatton
321

Ich habe das gleiche Problem. Der folgende Code funktioniert jedoch für mich: Überprüfen Sie, ob Ihr Paketname korrekt ist. Sie müssen auf das Root-Paket Ihrer Android-Anwendung verweisen.

private String getStringResourceByName(String aString) {
      String packageName = getPackageName();
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }
leonvian
quelle
9
Wenn jemand einen guten Grund dafür hat (z. B. enthalten Datendateien eine benutzerdefinierte Zeichenfolge, die entscheidet, welche Ressourcenzeichenfolge angezeigt werden soll, oder wenn diese Zeichenfolge aus dem Internet abgerufen wird), möchte ich darauf hinweisen Diese Lösung ist die richtige. Korrigieren Sie insbesondere den Teil, in dem sich der Ressourcentyp befindet stringund nicht strings. Weil das logisch ist (wie der Rest des Android). Also, danke dafür (und mehr), @leonvian. :-)
Ivan Vučica
2
@Sameer, um ein Array von Strings zu erhalten, verwenden Sie einfach: res.getStringArray (R.array.planets_array);
Werfen
3
Cool. Um eine separate Methodendeklaration loszuwerden, kann dies folgendermaßen "vereinfacht" werden : String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));.
Neurotransmitter
80

Nicht nur von Aktivitäten:

    public static String getStringByIdName(Context context, String idName) {
        Resources res = context.getResources();
        return res.getString(res.getIdentifier(idName, "string", context.getPackageName()));
    }
konmik
quelle
es hat super
geklappt
39
getResources().getString(getResources().getIdentifier("propertyName", "string", getPackageName()))
TOUDIdel
quelle
26

Ich würde der Lösung von leonvian etwas hinzufügen. Wenn also die Zeichenfolge zufällig nicht in den Ressourcen gefunden wird (Rückgabewert 0, das ist kein gültiger Ressourcencode), gibt die Funktion möglicherweise Folgendes zurück:

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

Bester Ansatz

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

Funktioniert überall (Utils, Modelle auch).

Ich habe alle Antworten gelesen, alle Antworten können Ihre Arbeit erledigen.

  • Sie können getString(R.string.some_string_id)in beiden Activityoder verwenden Fragment.
  • Sie können verwenden, Context.getString(R.string.some_string_id)wenn Sie keinen direkten Zugriff auf die getString()Methode haben. Wie Dialog.

Problem

Wenn Sie keinen ContextZugriff haben , wie eine Methode in Ihrer UtilKlasse.

Nehmen Sie die folgende Methode ohne Kontext an.

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

Jetzt werden Sie Contextals Parameter in dieser Methode übergeben und verwendengetString().

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

Was ich tue ist

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

Was? Es ist sehr einfach, überall in Ihrer App zu verwenden!

Hier ist also eine Lösung, mit der Sie von überall auf Ressourcen zugreifen können 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;
    }

}

Fügen Sie Ihrem manifest.xml <applicationTag ein Namensfeld hinzu.

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

Jetzt können Sie loslegen. Verwenden Sie App.getAppResources().getString(R.string.some_id)überall in der App.

Khemraj
quelle
+1 einfache und saubere Lösung. Beachten Sie eine schlechte Rechtschreibung getResourses, die getResourceszu einem Überschreiben führen würde. Auch das Singleton-Muster scheint unnötig, könnte möglicherweise übersprungen werden. Gibt es Probleme mit Speicherlecks bei dieser Lösung?
Xarvalus
@Xarvalus Lässt dies Speicher verlieren?
Khemraj
in meiner App alles in Ordnung :) Ich frage mich nur, ob jemand ein Problem damit hatte. Ich werde es wissen lassen, wenn ich auf eine Falle stoße.
Xarvalus
1
@Xarvalus Memory Leak tritt normalerweise an der Stelle auf, an der eine Variable verwendet wird, selbst wenn die übergeordnete Klasse zerstört wird. Wie bei Aktivitäten, Fragmente. Ich glaube nicht, dass es in diesem Fall passieren wird.
Khemraj
14

Eine einfache Möglichkeit, Ressourcenzeichenfolgen von Zeichenfolgen in eine Textansicht abzurufen. Hier ist resourceName der Name der Ressource

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

Wenn Sie keine Aktivitätsreferenz haben, können Sie Ihren Kontext folgendermaßen verwenden:

getContext().getString(R.string.your_string_name);
Hazlo8
quelle
4

Es gibt auch eine Reihe vordefinierter Android-Zeichenfolgen wie "Ok", "Abbrechen" und viele andere - Sie müssen also nicht alle deklarieren. Sie sind einfach erhältlich bei:

getString(android.R.string.ok)

(In diesem Fall "Ok" Zeichenfolge). Übrigens gibt es auch andere Android-Ressourcen wie zum Beispiel Symbole Bilder usw.

Forsberg
quelle
2

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

einfacher Weg

Avinash
quelle
1

Sie können dies in einer Aktivität versuchen:

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

In anderen Situationen wie Fragmenten, ... verwenden

getContext().getResources().getString(R.string.your string name);
M Shafaei N.
quelle
0

Zur Sicherheit sollten Sie Folgendes hinzufügen: mContext.getResources (). GetString (R.string.your_string);

mContext kann sein: Kontext in onAttach () von Fragment oder this of Activity.

O Thạnh Ldt
quelle
0

Wenn Sie es in eine Aktivität oder ein Fragmnet bekommen möchten, dann:

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

Wenn Sie es von einer Klasse außerhalb einer Aktivität oder eines Fragments erhalten möchten, in der Sie nicht über den Aktivitätskontext verfügen, verwenden Sie den Anwendungskontext:

getApplicationContext().getResources().getString(R.string.string_name);
rohegde7
quelle
0
R.string.<string_name>

Verwenden Sie diese Zeile direkt in Ihrer Java-Datei. Halte es einfach.

Owais Yosuf
quelle