เป็นไปได้ไหมที่จะเพิ่ม String to String.xml ใน Android แบบไดนามิก?


495

เป็นไปได้หรือไม่ที่จะมีตัวยึดตำแหน่งในค่าสตริงstring.xmlที่สามารถกำหนดค่าในขณะใช้งานได้

ตัวอย่าง:

บางสตริงPLACEHOLDER1บางสตริงเพิ่มเติม



@HarishGyanani ไม่คนนี้แก่แล้วควรรวมเข้ากับคนนี้แทน
Danh

คำตอบ:


1035

การจัดรูปแบบและจัดแต่งทรงผม

ใช่ดูสิ่งต่อไปนี้จากทรัพยากรสตริง: การจัดรูปแบบและจัดแต่งทรงผม

หากคุณต้องการจัดรูปแบบสตริงของคุณโดยใช้String.format(String, Object...)คุณสามารถทำได้โดยใส่อาร์กิวเมนต์รูปแบบของคุณในทรัพยากรสตริง ตัวอย่างเช่นด้วยทรัพยากรต่อไปนี้:

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

ในตัวอย่างนี้สตริงรูปแบบมีสองอาร์กิวเมนต์: %1$sเป็นสตริงและ%2$dเป็นตัวเลขทศนิยม คุณสามารถจัดรูปแบบสตริงด้วยอาร์กิวเมนต์จากแอปพลิเคชันของคุณเช่นนี้:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

การใช้งานพื้นฐาน

โปรดทราบว่าgetStringมีการโอเวอร์โหลดที่ใช้สตริงเป็นสตริงรูปแบบ:

String text = res.getString(R.string.welcome_messages, username, mailCount);

พหูพจน์

หากคุณต้องการจัดการกับพหูพจน์ใช้สิ่งนี้:

<plurals name="welcome_messages">
    <item quantity="one">Hello, %1$s! You have a new message.</item>
    <item quantity="other">Hello, %1$s! You have %2$d new messages.</item>
</plurals>

mailCountพารามิเตอร์แรกถูกใช้เพื่อตัดสินใจว่ารูปแบบใดที่จะใช้ (เดี่ยวหรือพหูพจน์) อีกพารามิเตอร์หนึ่งคือการแทนที่ของคุณ:

Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);

ดูทรัพยากร String: พหูพจน์สำหรับรายละเอียดเพิ่มเติม


61
การโทร String.format ในตัวอย่างโค้ดแรกนั้นไม่จำเป็นจริงๆแล้ว Resources.getString () รองรับการจัดรูปแบบดูที่: developer.android.com/reference/android/content/res/… , java.lang.Object ... )
Arnaud

16
สำหรับ Plurals ใน String.xml คุณต้องให้ id เป็น R.plurals.welcome_messages แทน R.string.welcome_messages
om252345

พหูพจน์กลับมาเฉพาะสตริงไอเท็มสุดท้ายเท่านั้น ... ความคิดใด ๆ ที่จะได้รับต่อท้ายสตริงได้อย่างไร
CoDe

1
เมื่อใช้วิธีนี้ในการจัดรูปแบบสตริงของคุณมันจะลบเมตาแท็กใด ๆ ที่คุณอาจใช้เช่นไฮเปอร์ลิงก์ ฯลฯ ที่อาจมีอยู่ในข้อความสตริง xml
Jonathan

4
สตริงย่อมาจาก% 1 $ s, ทศนิยมสำหรับ% 2 $ d และจำนวนเต็มหมายถึงอะไร ความหมาย% 1,% 2. การนับพารามิเตอร์นี้คืออะไรถ้าฉันต้องการพารามิเตอร์ที่สามพูดถึง% 3
reegan29

260

คำตอบเพิ่มเติม

เมื่อฉันเห็นครั้งแรก%1$sและ%2$dในคำตอบที่ยอมรับก็ไม่สมเหตุสมผล นี่คือคำอธิบายเพิ่มเติมเล็กน้อย

พวกเขาเรียกว่าตัวระบุรูปแบบ ในสตริง xml พวกเขาอยู่ในรูปแบบของ

%[parameter_index$][format_type] 
  • % : เครื่องหมายเปอร์เซ็นต์เป็นจุดเริ่มต้นของตัวระบุรูปแบบ
  • ดัชนีพารามิเตอร์ : นี่คือตัวเลขตามด้วยเครื่องหมายดอลลาร์ หากคุณมีสามพารามิเตอร์ที่คุณอยากจะใส่ลงในสตริงแล้วพวกเขาก็จะเรียกว่า1$, และ2$ 3$คำสั่งซื้อที่คุณวางไว้ในสตริงทรัพยากรนั้นไม่สำคัญเพียงแค่คำสั่งซื้อที่คุณจัดหาพารามิเตอร์เท่านั้น
  • ประเภทรูปแบบ : มีหลายวิธีที่คุณสามารถจัดรูปแบบสิ่งต่าง ๆ ( ดูเอกสารประกอบ ) นี่คือบางส่วนที่พบบ่อย:

    • s เชือก
    • d จำนวนเต็มทศนิยม
    • f จำนวนจุดลอยตัว

ตัวอย่าง

เราจะสร้างสตริงที่จัดรูปแบบต่อไปนี้โดยที่ส่วนสีเทาถูกแทรกโดยทางโปรแกรม

น้องสาวของฉันMaryเป็น12ปี

string.xml

<string name="my_xml_string">My sister %1$s is %2$d years old.</string>

MyActivity.java

String myString = "Mary";
int myInt = 12;
String formatted = getString(R.string.my_xml_string, myString, myInt);

หมายเหตุ

  • ฉันสามารถใช้getStringเพราะฉันอยู่ในกิจกรรม คุณสามารถใช้context.getResources().getString(...)หากไม่สามารถใช้ได้
  • String.format() จะจัดรูปแบบสตริงด้วย
  • 1$และ2$แง่ไม่จำเป็นต้องนำมาใช้ในการสั่งซื้อที่ นั่นคือสามารถมาก่อน2$ 1$สิ่งนี้มีประโยชน์เมื่อทำการแอปพลิเคชันสากลสำหรับภาษาที่ใช้ลำดับของคำต่างกัน
  • คุณสามารถใช้ตัวระบุรูปแบบได้%1$sหลายครั้งใน xml หากคุณต้องการทำซ้ำ
  • ใช้%%เพื่อรับ%ตัวละครจริง
  • สำหรับรายละเอียดเพิ่มเติมอ่านบทช่วยสอนที่มีประโยชน์ต่อไปนี้: เคล็ดลับด่วนสำหรับ Android SDK: การจัดรูปแบบสตริงทรัพยากร

125

เมื่อคุณต้องการใช้พารามิเตอร์จากไฟล์ strings.xml จริงโดยไม่ต้องใช้โค้ด Java ใด ๆ :

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY appname "WhereDat">
  <!ENTITY author "Oded">
]>

<resources>
    <string name="app_name">&appname;</string>
    <string name="description">The &appname; app was created by &author;</string>
</resources>

สิ่งนี้ใช้ไม่ได้กับไฟล์ทรัพยากรนั่นคือต้องคัดลอกตัวแปรไปยังไฟล์ XML แต่ละไฟล์ที่ต้องการ


เป็นคำตอบที่ดียกเว้นเมื่อคุณมีพารามิเตอร์ใน<! [CDATA [& param; ]]>
Hermann Poilpre

2
มีวิธีการกำหนด<!DOCTYPE... ]>ส่วนในไฟล์แยกและรวมไว้ในไฟล์ทรัพยากรหลาย ๆ ? เคล็ดลับเพื่อให้บรรลุนี้
prom85

18

กำลังมองหาสิ่งเดียวกันและในที่สุดก็พบทางออกที่ง่ายมากดังต่อไปนี้ ดีที่สุด: ทำงานนอกกรอบ
1. แก้ไขข้อความที่เป็นสตริงของคุณ:

<string name="welcome_messages">Hello, <xliff:g name="name">%s</xliff:g>! You have 
<xliff:g name="count">%d</xliff:g> new messages.</string>

2. ใช้การแทนที่สตริง:

c.getString(R.string.welcome_messages,name,count);

โดยที่ c คือบริบทชื่อเป็นตัวแปรสตริงและนับตัวแปร int ของคุณ

คุณจะต้องรวม

<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">

ใน res / strings.xml ของคุณ ได้ผลสำหรับฉัน :)


2
จุดคืออะไรxliffแท็กรอบ specifiers รูปแบบ? พวกเขาจะเพิ่มมูลค่าพิเศษอะไรเมื่อเทียบกับการใช้%sและตัว%dระบุเฉพาะด้วยตนเอง?
Richard Le Mesurier

แอตทริบิวต์ "name" ในแท็ก xliff เป็นเพียงวิธีการให้คำแนะนำแก่นักแปลเกี่ยวกับสิ่งที่จะถูกแทนที่ในนั้น บางครั้งมันไม่ง่ายเลยที่จะเดาว่า "% s" หมายถึงอะไร
hugomg

3

ใน Kotlin คุณเพียงแค่ต้องตั้งค่าสตริงของคุณดังนี้:

<string name="song_number_and_title">"%1$d ~ %2$s"</string>

สร้างมุมมองข้อความบนเค้าโครงของคุณ:

<TextView android:id="@+id/song_number_and_title"/>

จากนั้นทำสิ่งนี้ในรหัสของคุณหากคุณใช้ Anko:

val song = database.use { // get your song from the database }
song_number_and_title.setText(resources.getString(R.string.song_number_and_title, song.number, song.title))  

คุณอาจต้องรับทรัพยากรจากบริบทแอปพลิเคชัน


5
มันแตกต่างจากตัวอย่าง java อย่างไร? ฉันไม่เห็นความแตกต่าง
Janusz Hain


1

ใน res / values ​​/ string.xml

<resources>
    <string name="app_name">Hello World</string>
    <string name="my_application">Application name: %s, package name: %s</string>
</resources>

ในรหัส java

String[] args = new String[2];
args[0] = context.getString(R.string.app_name);
args[1] = context.getPackageName();
String textMessage = context.getString(R.string.my_application,(Object[]) args);


1

หากคุณต้องการเขียนเปอร์เซ็นต์ (%) ให้ทำซ้ำ:

<string name="percent">%1$d%%</string>

label.text = getString(R.string.percent, 75) // Output: 75%.

ถ้าคุณเขียนเพียงแค่คุณจะได้รับข้อผิดพลาด:%1$d%Format string 'percent' is not a valid format string so it should not be passed to String.format


0

ใช่ คุณสามารถทำได้โดยไม่ต้องเขียนโค้ด Java / Kotlin ใด ๆ เพียง XML โดยใช้ไลบรารี่ขนาดเล็กที่ฉันสร้างขึ้นซึ่งจะทำที่ buildtime ดังนั้นแอปของคุณจะไม่ได้รับผลกระทบ: https://github.com/LikeTheSalad/android -string อ้างอิง

การใช้

สายของคุณ:

<resources>
    <string name="app_name">My App Name</string>
    <string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>

สตริงที่สร้างขึ้นหลังการสร้าง:

<!--resolved.xml-->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>

0

วิธีแก้ปัญหาโดยตรง Kotlin:

strings.xml

<string name="customer_message">Hello, %1$s!\nYou have %2$d Products in your cart.</string>

kotlinActivityORFragmentFile.kt:

val username = "Andrew"
val products = 1000
val text: String = String.format(
      resources.getString(R.string.customer_message), username, products )

0

ในไฟล์สตริงของคุณใช้สิ่งนี้

<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>

และในรหัสของคุณใช้ตาม

coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
                        , rewardPoints.getConversion_rate(), getString(R.string.rs)));

-1

รุ่น Kotlin ของคำตอบที่ยอมรับ ...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)

3
วิธีที่ถูกต้องมากขึ้นคือการใช้วิธีการที่มีการขัดแย้งแทนresources.getString(int, ... args) String.formatไม่มี kotlin เฉพาะในรหัสนี้อย่างใดอย่างอื่นแล้วvalคำหลัก ดูคำตอบของ msbodw001
dant3
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.