Android: Bagaimana cara mendapatkan string dari sumber daya menggunakan namanya?

553

Saya ingin memiliki 2 bahasa untuk UI dan nilai string terpisah untuk mereka dalam file sumber saya 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>

Sekarang saya perlu mengambil nilai-nilai ini secara dinamis di aplikasi saya:

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

Masalah saya adalah itu i = 0.

Mengapa itu tidak berhasil dalam kasus saya?

Ivan
sumber
1
Apakah Anda yakin bahwa Central.lang adalah salah satu enatau ru?
K-ballo
1
Info lebih lanjut diperlukan untuk memeriksa kode Anda. apa keadaan masing-masing var sebelum mendapatkan saya? Bagaimanapun, Anda harus menggunakan dukungan lokalisasi default di Android untuk menjaga hal-hal sederhana.
Alin

Jawaban:

1069

Tautan yang Anda maksud tampaknya berfungsi dengan string yang dihasilkan saat runtime. String dari strings.xml tidak dibuat saat runtime. Anda bisa mendapatkannya melalui

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

getResources()adalah metode Contextkelas. Jika Anda berada di dalam a Activityatau Service(yang memperluas Konteks) Anda dapat menggunakannya seperti dalam cuplikan ini.

Juga perhatikan bahwa seluruh ketergantungan bahasa dapat diatasi oleh kerangka kerja android . Cukup buat folder yang berbeda untuk setiap bahasa. Jika bahasa Inggris adalah bahasa default Anda, cukup masukkan string bahasa Inggris ke dalamnya res/values/strings.xml. Kemudian buat folder baru values-rudan masukkan string Rusia dengan nama yang identik ke dalam res/values-ru/strings.xml. Dari titik ini pada android memilih yang benar tergantung pada lokasi perangkat untuk Anda, baik ketika Anda menelepon getString()atau ketika mereferensikan string dalam XML via @string/mystring. Yang dari res/values/strings.xmladalah yang mundur, jika Anda tidak memiliki folder yang mencakup lokal pengguna, yang ini akan digunakan sebagai nilai default.

Lihat Pelokalan dan Sumber Daya Penyedia untuk informasi lebih lanjut.


sumber
23
Jika Anda berada dalam suatu android.support.v4.app.Fragment, Anda bisa getString(R.string.mystring)langsung menelepon .
JaKXz
3
Saya hanya berkeliaran. Mengapa itu dilakukan (oleh google) sedemikian rumitnya? Pertama, dapatkan ID numerik dari mystring (dari objek R) dan kemudian dapatkan string dengan ID itu? Dan di mana pasangan "ID-of-mystring => actualValue" sebenarnya berada? Sejauh yang saya tahu mystring => ID-of-mystring ada di R.java, tapi hanya itu :)
Lukáš Řádek
2
pastikan bahwa "R" adalah R proyek Anda bukan Android R. default
ralphgabb
2
Ini mungkin jawaban yang dibutuhkan tetapi bukan jawaban yang diminta! Untuk mengakses sumber string secara dinamis dengan nama, lihat jawaban dari @leonvian ... yang harus diterima sebagai IMO
Chris Hatton
321

Saya memiliki masalah yang sama. Tetapi kode di bawah ini berfungsi untuk saya: Verifikasi apakah nama paket Anda benar. Anda harus merujuk untuk paket root aplikasi Android Anda.

private String getStringResourceByName(String aString) {
      String packageName = getPackageName();
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }
leonvian
sumber
9
Jika seseorang memiliki alasan kuat untuk melakukan ini (misalnya, file data berisi string khusus yang memutuskan string sumber mana yang harus ditampilkan, atau jika string ini diambil dari Internet) - maka saya ingin menunjukkan bahwa solusi ini adalah yang benar. Terutama perbaiki bagian di mana jenis sumber daya berada stringdan tidak strings. Karena itu logis (seperti Android lainnya). Jadi, terima kasih untuk itu (dan banyak lagi), @levian. :-)
Ivan Vučica
2
@Sameer untuk mendapatkan array dengan Strings cukup gunakan: res.getStringArray (R.array.planets_array); Lihatlah tautan resmi ini: developer.android.com/guide/topics/resources/…
leonvian
3
Keren. Untuk menyingkirkan deklarasi metode terpisah, ini bisa "disederhanakan" sedemikian rupa: String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));.
Neurotransmitter
80

Bukan hanya dari kegiatan:

    public static String getStringByIdName(Context context, String idName) {
        Resources res = context.getResources();
        return res.getString(res.getIdentifier(idName, "string", context.getPackageName()));
    }
konmik
sumber
itu bekerja dengan baik terima kasih
Mosa
39
getResources().getString(getResources().getIdentifier("propertyName", "string", getPackageName()))
TOUDIdel
sumber
26

Saya akan menambahkan sesuatu ke solusi leonvian, jadi jika kebetulan string tidak ditemukan di antara sumber daya (nilai pengembalian 0, itu bukan kode sumber daya yang valid), fungsi mungkin mengembalikan sesuatu:

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
sumber
15

Pendekatan Terbaik

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

Akan bekerja di mana saja (Utils, Model juga).

Saya telah membaca semua jawaban, semua jawaban dapat membuat pekerjaan Anda selesai.

  • Anda dapat menggunakan getString(R.string.some_string_id)keduanya Activityatau Fragment.
  • Anda dapat menggunakan di Context.getString(R.string.some_string_id)mana Anda tidak memiliki akses langsung ke getString()metode. Seperti Dialog.

Masalah

Ketika Anda tidak memiliki Contextakses , sukai metode di Utilkelas Anda .

Asumsikan metode di bawah ini tanpa Konteks.

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

Sekarang Anda akan lulus Contextsebagai parameter dalam metode ini dan gunakangetString().

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

Apa yang saya lakukan adalah

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

Apa? Sangat mudah digunakan di mana saja di aplikasi Anda!

Jadi, inilah solusi yang dapat digunakan untuk mengakses sumber daya dari mana saja 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;
    }

}

Tambahkan bidang nama ke manifest.xml <applicationtag Anda .

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

Sekarang kamu baik untuk pergi. Gunakan App.getAppResources().getString(R.string.some_id)di mana saja di aplikasi.

Khemraj
sumber
+1 solusi sederhana & bersih. Perhatikan ejaan yang buruk getResourses, getResourcespenyebabnya akan ditimpa. Juga pola singleton tampaknya tidak perlu, mungkin bisa dilewati. Adakah memori yang bocor masalah dengan solusi ini?
Xarvalus
@Xarvalus Apakah ini membuat memori bocor?
Khemraj
dalam aplikasi saya baik-baik saja :) hanya ingin tahu apakah ada yang punya masalah dengan itu. Saya akan memberi tahu jika saya menemukan jebakan.
Xarvalus
1
@Xarvalus Memory Leak biasanya terjadi di tempat di mana variabel sedang digunakan bahkan kelas induk dihancurkan. Seperti dalam Aktivitas, Fragmen. Saya tidak berpikir itu akan terjadi dalam kasus ini.
Khemraj
14

Cara sederhana untuk mendapatkan string sumber daya dari string ke TextView. Di sini resourceName adalah nama resource

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

Jika Anda tidak memiliki referensi Aktivitas, Anda dapat menggunakan konteks Anda dengan cara ini:

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

Ada juga satu set string Android yang telah ditentukan sebelumnya seperti "Oke", "Batal" dan banyak lainnya - sehingga Anda tidak perlu mendeklarasikan semua. Mereka tersedia hanya dengan:

getString(android.R.string.ok)

(Dalam hal ini, string "Oke"). BTW ada juga sumber daya Android lain yang tersedia seperti misalnya ikon gambar dll.

forsberg
sumber
2

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

jalan mudah

Avinash
sumber
1

Anda dapat mencoba ini dalam suatu Kegiatan:

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

Dalam situasi lain seperti fragmen, ... gunakan

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

Untuk amannya, Anda harus menambahkan: mContext.getResources (). GetString (R.string.your_string);

mContext dapat berupa: konteks di onAttach () dari Fragmen atau ini dari Activity.

O Thạnh Ldt
sumber
0

Jika Anda tidak bisa mendapatkannya di dalam suatu aktivitas atau fragmnet, maka:

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

Jika Anda ingin mendapatkannya dari kelas di luar aktivitas atau fragmen di mana Anda tidak memiliki konteks aktivitas kemudian gunakan konteks aplikasi:

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

Gunakan baris itu langsung di file java Anda. Tetap sederhana.

Owais Yosuf
sumber