Android Spanned, SpannedString, Spannable, SpannableString และ CharSequence


96

ข้อเสนอของ Android ที่มีความหลากหลายของการเชื่อมต่อทั้งหมดที่เกี่ยวข้องกับข้อความและสตริง: Spanned, SpannedString, Spannable, และSpannableStringCharSequence

ฉันได้ใช้สิ่งที่กล่าวมาทั้งหมดในสถานการณ์ต่างๆโดยปกติหลังจากใช้Html.fromHtml()เพื่อแสดงข้อความที่เชื่อมโยงได้ภายใน a TextViewเพื่อใช้สไตล์บางอย่างกับมัน

ฉันได้พยายามทำความเข้าใจวัตถุประสงค์ / การใช้งานอินเทอร์เฟซเหล่านี้จากเอกสารอย่างเป็นทางการของ Android และล้มเหลวเนื่องจากค่อนข้างสับสน .. อินเทอร์เฟซเหล่านี้มีจุดประสงค์อะไร? มักใช้ในสถานการณ์ใด ควรหลีกเลี่ยงการใช้ในกรณีใด มีผลกระทบด้านประสิทธิภาพที่ชัดเจนที่ต้องพิจารณาเมื่อใช้อย่างใดอย่างหนึ่งหรือไม่?

หากใครสามารถให้คำอธิบายที่ดีได้จะได้รับการชื่นชมมาก

คำตอบ:


149

อะไรคือจุดประสงค์ของอินเทอร์เฟซเหล่านี้?

แผนภาพจาก yuml.me/edit/5f8da6cb CharSequenceเป็นอินเตอร์เฟส Java มาตรฐานที่แสดงลำดับของอักขระ Stringคือการปฏิบัติที่เป็นรูปธรรมมากที่สุดที่ใช้ตามด้วยCharSequenceStringBuilder

Spannedเป็นCharSequence"ช่วง" ที่ระบุการจัดรูปแบบเพื่อใช้กับส่วนของข้อความโดยที่ช่วงเหล่านั้นไม่สามารถแก้ไขได้

SpannableคือการSpannedเพิ่มความสามารถในการแก้ไขช่วง (เพื่อเพิ่มหรือลบการจัดรูปแบบ) แต่ไม่สามารถแก้ไขข้อความได้

SpannedStringคือการนำSpannedอินเทอร์เฟซมาใช้อย่างเป็นรูปธรรม

SpannableStringคือการนำSpannableอินเทอร์เฟซมาใช้อย่างเป็นรูปธรรม

มักใช้ในสถานการณ์ใด

เมื่อมีเมธอดที่คืนค่าหนึ่ง (เช่นgetText()บน an EditText) หรือเมื่อมีวิธีที่รับหนึ่งเป็นพารามิเตอร์ (เช่นsetText()บน a TextView) แผนภาพจาก yuml.me/edit/35c8f39f

กรณีการใช้งานที่คุณอ้างถึงHtml.fromHtml()อาจเป็นเรื่องธรรมดาที่สุดในการพัฒนา Android ทั่วไปเนื่องจาก a TextViewมีSpannedน้ำหนักเบากว่าไฟล์WebView. อย่างไรก็ตามมีกรณีการใช้งานอื่น ๆ เช่น:

ควรหลีกเลี่ยงการใช้ในกรณีใด

พวกเขาแย่มากในการต่อสู้กับศีรษะล้านการกำจัดหิมะการซ่อมแซมปั๊มความร้อนการทำโซเฟเล่ ฯลฯ

:-)

มีผลกระทบด้านประสิทธิภาพที่ชัดเจนที่ต้องพิจารณาเมื่อใช้อย่างใดอย่างหนึ่งหรือไม่?

อินเทอร์เฟซตามคำจำกัดความไม่มี "ผลกระทบด้านประสิทธิภาพ" - เป็นเพียงคำอธิบายของ API

ฉันไม่ทราบว่าSpannableStringช้ากว่าSpannedStringการดำเนินการใด ๆ อย่างมาก อย่างไรก็ตามSpannableStringBuilder(ซึ่งอนุญาตให้จัดการข้อความนอกเหนือจากช่วงที่จัดรูปแบบข้อความนั้น) อาจช้ากว่าSpannableStringหรือSpannedStringสำหรับสิ่งต่างๆเล็กน้อย ความแตกต่างของประสิทธิภาพเพียงพอหรือไม่นั้นขึ้นอยู่กับการใช้งาน


4
เนื่องจากเอกสารอย่างเป็นทางการเงียบคุณได้ข้อมูลเหล่านี้มาจากไหน? แหล่งข้อมูลด้วยตนเองเรียกดูวิธีที่ไม่ยอมใครง่ายๆ?
Pacerier

11
@Pacerier: ฉันไม่แน่ใจว่าคุณอ้างถึงส่วนไหนของคำตอบนี้ ตัวอย่างเช่นลำดับชั้นของคลาสที่อธิบายไว้ในคำตอบนี้ส่วนใหญ่มาจากเอกสารโดยเฉพาะ JavaDocs ในทางกลับกันการขาดประโยชน์จากสิ่งเหล่านี้ในการต่อสู้กับอาการศีรษะล้านมาจากการสังเกตส่วนบุคคล
CommonsWare

@CommonsWare นั่นหมายความว่าสตริงที่มีรอยยิ้มอยู่ระหว่างนั้นจะถือว่าเป็นspannableStringและไม่ใช่แบบปกติ .. เพราะฉันกำลังเผชิญกับความล่าช้าอย่างมากsetText(my_string) เมื่อmy_stringมีรอยยิ้มอยู่ในนั้น (เช่น watsapp) เมื่อเทียบกับสตริงปกติ . (ซึ่งมี แต่ข้อความธรรมดา) กรุณาสาดแสง ... อย่างใดฉันเชื่อว่า smilleys ไม่ใช่ข้อความ (unicode) เท่านั้น
eRaisedToX

1
@eRaisedToX: รอยยิ้มสามารถใช้เป็นอีโมจิหรือรูปภาพได้ AFAIK อีโมจิจะเป็นอักขระ Unicode แต่ละตัวและน่าจะอยู่ในสตริงปกติ ภาพจะต้องซึ่งจะต้องใช้ImageSpan SpannableString
CommonsWare

น่าจะแน่ใจ ... แต่ลองจัดการกับอิโมจิและใช้สตริงปกติแล้วคุณจะกลับมาต่อสู้กับอาการศีรษะล้านได้ทันที แก้ไขได้และ SpannableStringBuilders เป็นเพื่อนที่ดีที่สุดของคุณในการใช้อิโมจิ ฉันพบว่าแม้ว่าจะใช่มันเป็นเพียง Unicode แต่ก็เป็นวิธีที่คุณเขียนโค้ดเพื่อระบุช่วงอีโมจิและการตั้งค่าช่วงอีโมจิซึ่งเป็นจุดที่ต้นทุนด้านประสิทธิภาพของคุณกำลังมาโปรดระวังการใช้ไลบรารีอิโมจิของคนอื่นหากคุณไม่ทราบ ทำงานอย่างไร ...
JamisonMan111

45

สตริง

A Stringไม่เปลี่ยนรูป (กล่าวคือข้อความไม่สามารถเปลี่ยนแปลงได้) นอกจากนี้ยังไม่มีระยะเวลาที่เกี่ยวข้อง (ช่วงคือช่วงของข้อความที่มีข้อมูลการจัดรูปแบบเช่นสีการไฮไลต์ตัวเอียงลิงก์ ฯลฯ ) ดังนั้นคุณสามารถใช้Stringข้อความเมื่อไม่จำเป็นต้องเปลี่ยนแปลงและไม่จำเป็นต้องจัดรูปแบบใด ๆ

StringBuilder

A StringBuilderมีข้อความที่ไม่แน่นอนดังนั้นคุณสามารถแก้ไขได้โดยไม่ต้องสร้างวัตถุใหม่ อย่างไรก็ตามไม่มีข้อมูลช่วงใด ๆ มันเป็นเพียงข้อความธรรมดา ดังนั้นใช้ a StringBuilderเมื่อคุณต้องการเปลี่ยนข้อความ แต่คุณไม่สนใจเกี่ยวกับการจัดรูปแบบ

SpannedString

A SpannedStringมีข้อความที่ไม่เปลี่ยนรูป (เช่น a String) และข้อมูลช่วงที่ไม่เปลี่ยนรูป เป็นการดำเนินการตามข้อกำหนดที่กำหนดโดยSpannedอินเทอร์เฟซอย่างใช้SpannedStringเมื่อข้อความของคุณมีสไตล์ แต่คุณไม่จำเป็นต้องเปลี่ยนข้อความหรือสไตล์หลังจากสร้างแล้ว

บันทึก:ไม่มีสิ่งที่เรียกว่า a SpannedStringBuilderเพราะหากข้อความเปลี่ยนไปข้อมูลสแปนก็มีแนวโน้มที่จะต้องเปลี่ยนไปเช่นกัน

SpannableString

A SpannableStringมีข้อความที่ไม่เปลี่ยนรูป แต่ข้อมูลช่วงจะไม่แน่นอน เป็นการดำเนินการตามข้อกำหนดที่กำหนดโดยSpannableอินเทอร์เฟซอย่างเป็นรูปธรรม ใช้SpannableStringเมื่อข้อความของคุณไม่จำเป็นต้องเปลี่ยนแปลง แต่มีการกำหนดสไตล์

SpannableStringBuilder

A SpannableStringBuilderมีทั้งข้อความที่ไม่แน่นอนและข้อมูลช่วง เป็นการนำข้อกำหนดที่กำหนดโดยSpannableและEditableอินเทอร์เฟซอินเทอร์เฟซ (อื่น ๆ ) อย่างใช้SpannableStringBuilderเมื่อคุณต้องการอัปเดตข้อความและรูปแบบ

CharSequence

A CharSequenceคืออินเทอร์เฟซไม่ใช่คลาสที่เป็นรูปธรรม นั่นหมายความว่ามันเพียงแค่กำหนดรายการของกฎที่จะปฏิบัติตามสำหรับคลาสใด ๆ ที่ใช้มัน และคลาสทั้งหมดที่กล่าวถึงข้างต้นนำไปใช้ ดังนั้นคุณสามารถใช้CharSequenceเมื่อคุณต้องการสรุปประเภทของวัตถุที่คุณมีเพื่อความยืดหยุ่นสูงสุด คุณสามารถดาวน์แคสต์เป็นStringหรือSpannableStringBuilderหรืออะไรก็ได้ในภายหลังหากคุณต้องการ


4
ฉันขอขอบคุณที่คุณนำเสนอคำตอบของคุณอ่านและเข้าใจง่ายมากขอบคุณ
JamisonMan111
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.