Referensi string dalam sumber daya array string dengan xml

256

Saya memiliki preferensi di mana Anda dapat mengaktifkan / menonaktifkan item apa yang akan muncul di menu. Ada 17 item. Saya membuat array string dalam values ​​/ arrays.xml dengan judul untuk masing-masing dari 17 item ini.

Saya memiliki preferensi.xml yang memiliki tata letak untuk file preferensi saya, dan saya ingin merujuk satu item dari array string untuk digunakan sebagai judul.

Bagaimana saya bisa melakukan ini?

Dalam referensi pengembang Android, saya melihat bagaimana saya bisa mereferensikan string tunggal dengan XML, tetapi tidak bagaimana saya bisa mereferensikan string dari sumber daya array dalam XML.

Jorsher
sumber

Jawaban:

331

Singkatnya: Saya tidak berpikir Anda bisa, tapi tampaknya ada solusi: .

Jika Anda melihat Sumber Daya Android di sini:

http://developer.android.com/guide/topics/resources/string-resource.html

Anda melihat daripada di bawah bagian array (array string, setidaknya), "REFERENSI SUMBERDAYA" (seperti yang Anda dapatkan dari XML) tidak menentukan cara untuk menangani masing-masing item. Anda bahkan dapat mencoba dalam XML untuk menggunakan "@ array / yourarrayhere". Saya tahu bahwa dalam waktu desain Anda akan mendapatkan item pertama. Tapi itu tidak ada gunanya jika Anda ingin menggunakan, katakanlah ... yang kedua, tentu saja.

NAMUN, ada trik yang bisa Anda lakukan. Lihat disini:

Merujuk string XML dalam Array XML (Android)

Anda dapat "menipu" (tidak benar-benar) definisi array dengan mengarahkan string independen DI DALAM definisi array. Misalnya, di strings.xml Anda:

<string name="earth">Earth</string>
<string name="moon">Moon</string>

<string-array name="system">
    <item>@string/earth</item>
    <item>@string/moon</item>
</string-array>

Dengan menggunakan ini, Anda dapat menggunakan "@ string / earth" dan "@ string / moon" secara normal di bidang "android: text" dan "android: title" XML Anda, namun Anda tidak akan kehilangan kemampuan untuk menggunakan array definisi untuk tujuan apa pun yang Anda maksudkan sejak awal.

Tampaknya bekerja di sini di Eclipse saya. Mengapa Anda tidak mencoba dan memberi tahu kami jika itu berhasil? :-)

davidcsb
sumber
32
jika kita hanya bisa memberikan nametag ke <item> s ... * sigh *
Some Noob Student
2
Baru saja mencobanya! Menentukan larik di default strings.xmltetapi tidak di values-frdan larik masih diperbarui dengan versi Perancis. Sangat salah .. tapi keren itu berhasil!
Blundell
1
Kiat cepat untuk siapa saja: Mengklik dua kali pada "bumi" akan menyorot bumi. Mengklik dua kali pada bulan di @ string / bulan akan menyoroti hanya bulan. Jadi, jika Anda menduplikasi item pertama beberapa kali ketika membangun array Anda, Anda kemudian dapat menyalin dan menempelkan antara string individual Anda dan array-string dengan cukup mudah. Mungkin bisa membantu mempercepat pembuatan string-array Anda :)
ArtOfWarfare
2
Hanya ingin tahu apakah pendekatan ini menyebabkan kinerja yang lebih buruk daripada jika saya mendeklarasikan string dalam array sebagaimana adanya tetapi tidak menggunakan referensi?
Alex Bonel
1
@AlexBonel pertanyaan yang menarik, dan sejujurnya saya tidak tahu. Bahkan jika itu akan, saya pikir kita harus meninggalkan optimasi seperti ini sangat mikro ke kompiler. Ngomong-ngomong, bukankah mereka berakhir diseret di suatu tempat di jalan? Saya kira mereka melakukannya, tetapi saya tidak yakin. Setidaknya pada level yang lebih tinggi dalam rantai Android, saya tahu Anda dapat membongkar APK sepenuhnya dengan apktool, dan itu akan memulihkan nama asli dari kunci string, yang berarti deklarasi referensi, seperti yang di atas, disimpan. Tapi saya tidak terlalu tertarik dengan bidang itu sekarang, jadi saya tidak bisa menjawab pertanyaan Anda. Ini pertanyaan yang bagus.
davidcsb
216

Mungkin ini akan membantu:

String[] some_array = getResources().getStringArray(R.array.your_string_array)

Jadi Anda mendapatkan daftar-array sebagai String [] dan kemudian memilih i, some_array [i].


sumber
10
Saya mengerti cara mendapatkan sumber daya array. Itu tidak memungkinkan saya untuk merujuk item dari array dalam tata letak xml.
Jorsher
1
Ah maaf. Saya salah paham. Nah, apakah harus dalam tata letak xml? Jika judul berubah dengan pilihan pengguna, mengapa tidak melakukannya di file .java. Misalnya .setText (some_array [i]).
2
Karena, tata letak preferensi dalam xml. Java memuat menu dengan item yang "diaktifkan" dalam preferensi. Mengetik 17 memeriksa preferensi, dan kode berikutnya untuk menambahkannya ke listview sepertinya berlebihan dan ceroboh bagi saya.
Jorsher
Ini berguna ketika saya membuat arrayadapter dari array xml di folder nilai saya
EHarpham
Saya menemukan ini berguna ketika membutuhkan nilai default ketika mendapatkan preferensi: di String myPref = preferences.getString(context.getResources().getString(R.string.my_pref), some_array [0]);mana my_pref sebelumnya diatur ke beberapa nilai some_array [x]
Al Lelopath
67

Pilihan yang lebih baik adalah dengan menggunakan array yang dikembalikan sumber daya sebagai array, yang berarti:

getResources().getStringArray(R.array.your_array)[position]

Ini adalah pendekatan pintas dari pendekatan yang disebutkan di atas tetapi melakukan pekerjaan dengan cara yang Anda inginkan. Kalau tidak, android tidak menyediakan pengindeksan XML langsung untuk array berbasis xml.

Amitesh
sumber
1
@ Benjiko99 terima kasih telah menemukan kesalahan, telah mengubahnya sesuai.
Amitesh
Ini adalah cara paling ringkas untuk melakukannya. +1!
suomi35
1
ini mungkin tampak lebih ringkas tetapi jika seseorang atau penerjemah mengubah urutan array dalam file string, Anda akan berakhir menggunakan string yang salah.
Pengembang baru
9

Sayangnya:

  • Tampaknya Anda tidak dapat mereferensikan satu item dari array dalam nilai / arrays.xml dengan XML. Tentu saja Anda bisa di Jawa, tetapi tidak XML. Tidak ada informasi tentang melakukannya di referensi pengembang Android, dan saya tidak dapat menemukan tempat lain.

  • Tampaknya Anda tidak dapat menggunakan array sebagai kunci dalam tata letak preferensi. Setiap kunci harus bernilai tunggal dengan nama kuncinya sendiri.

Apa yang ingin saya capai: Saya ingin dapat mengulang-ulang 17 preferensi, memeriksa apakah item dicentang, dan jika ya, muat string dari array string untuk nama preferensi itu.

Inilah kode yang saya harapkan akan menyelesaikan tugas ini:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());  
ArrayAdapter<String> itemsArrayList = new ArrayAdapter<String>(getBaseContext(),   android.R.layout.simple_list_item_1);  
String[] itemNames = getResources().getStringArray(R.array.itemNames_array);  


for (int i = 0; i < 16; i++) {  
    if (prefs.getBoolean("itemKey[i]", true)) {  
        itemsArrayList.add(itemNames[i]);  
    }  
} 

Apa yang saya lakukan:

  • Saya menetapkan string tunggal untuk setiap item, dan mereferensikan string tunggal di. Saya menggunakan referensi string tunggal untuk judul kotak centang preferensi tata letak, dan array untuk loop saya.

  • Untuk mengulang melalui preferensi, saya hanya memberi nama kunci seperti key1, key2, key3, dll. Karena Anda merujuk kunci dengan string, Anda memiliki opsi untuk "membangun" nama kunci saat runtime.

Ini kode baru:

for (int i = 0; i < 16; i++) {  
        if (prefs.getBoolean("itemKey" + String.valueOf(i), true)) {  
        itemsArrayList.add(itemNames[i]);  
    }  
}
Jorsher
sumber
1

Cara lain untuk melakukannya adalah mendefinisikan array sumber daya di strings.xml seperti di bawah ini.

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [
    <!ENTITY supportDefaultSelection "Choose your issue">
    <!ENTITY issueOption1 "Support">
    <!ENTITY issueOption2 "Feedback">
    <!ENTITY issueOption3 "Help">
    ]>

dan kemudian mendefinisikan array string menggunakan sumber daya di atas

<string-array name="support_issues_array">
        <item>&supportDefaultSelection;</item>
        <item>&issueOption1;</item>
        <item>&issueOption2;</item>
        <item>&issueOption3;</item>
    </string-array>

Anda bisa merujuk string yang sama ke xml lain juga menjaga DRY tetap utuh. Keuntungan yang saya lihat adalah, dengan perubahan nilai tunggal itu akan mempengaruhi semua referensi dalam kode.

Amruta-Pani
sumber