ในไฟล์ XML เราสามารถกำหนด ID ให้กับมุมมองที่ชอบandroid:id="@+id/something"
แล้วโทรfindViewById()
แต่เมื่อสร้างมุมมองโดยทางโปรแกรมฉันจะกำหนด ID ได้อย่างไร
ฉันคิดว่าsetId()
ไม่เหมือนกับการมอบหมายเริ่มต้น setId()
เป็นพิเศษ
ใครสามารถแก้ไขฉันได้ไหม
ในไฟล์ XML เราสามารถกำหนด ID ให้กับมุมมองที่ชอบandroid:id="@+id/something"
แล้วโทรfindViewById()
แต่เมื่อสร้างมุมมองโดยทางโปรแกรมฉันจะกำหนด ID ได้อย่างไร
ฉันคิดว่าsetId()
ไม่เหมือนกับการมอบหมายเริ่มต้น setId()
เป็นพิเศษ
ใครสามารถแก้ไขฉันได้ไหม
คำตอบ:
id
ภาพรวมAndroidAndroid id
เป็นจำนวนเต็มที่ใช้เพื่อระบุมุมมอง สิ่งนี้id
สามารถกำหนดผ่านทาง XML (เมื่อเป็นไปได้) และผ่านทางรหัส (โดยทางโปรแกรม) สิ่งid
ที่มีประโยชน์มากที่สุดสำหรับการรับการอ้างอิงสำหรับ XML ที่กำหนดโดยView
s ที่สร้างโดยInflater
(เช่นโดยใช้setContentView
)
id
ผ่านXML
android:id="@+id/
somename "
ให้กับมุมมองของคุณandroid:id
จะมีการกำหนดค่าเฉพาะ int
สำหรับใช้ในรหัสandroid:id
's int
ค่าในการใช้รหัส ' R.id.
somename'(อย่างมีประสิทธิภาพอย่างต่อเนื่อง.)int
สามารถเปลี่ยนจาก build เป็น buildดังนั้นอย่าคัดลอก idจากgen/
package.name/ R.java
เพียงแค่ใช้ " R.id.
somename"id
กำหนดให้กับPreference
ใน XML จะไม่ถูกใช้เมื่อPreference
สร้างขึ้นView
)id
รหัสผ่าน (โดยทางโปรแกรม)id
โดยใช้someView.setId(
int);
int
ต้องเป็นบวก แต่อย่างอื่น arbitrary- มันอาจเป็นสิ่งที่คุณต้องการ (ให้อ่านถ้านี้เป็นที่น่าตกใจ.)id
เอสXML
ที่ได้รับมอบหมายid
จะไม่ซ้ำกันid
s ทำไม่ได้จะต้องไม่ซ้ำกันid
s สามารถ (ทฤษฎี) ความขัดแย้งกับXML
-assigned id
sid
s จะไม่ว่าถ้าถามอย่างถูกต้อง(อ่านเก็บ)id
ไม่สำคัญfindViewById(int)
จะย้ำความลึกแรกซ้ำผ่านลำดับชั้นดูจากมุมมองที่คุณระบุและกลับคนแรกที่จะพบกับการจับคู่View
id
id
ก่อนที่ XML จะถูกกำหนดid
ในลำดับชั้นfindViewById(R.id.somename)
จะส่งคืนมุมมองที่กำหนดโดย XML ดังนั้นid
'dID
sViewGroup
id
LinearLayout
android:id="@+id/placeholder"
ViewGroup
ด้วยView
sid
ที่สะดวกสำหรับแต่ละมุมมองเคียวรีมุมมองชายด์เหล่านี้โดยใช้ placeholder.findViewById (convenientInt);
API 17 ที่แนะนำView.generateViewId()
ซึ่งช่วยให้คุณสร้าง ID ที่ไม่ซ้ำ
หากคุณเลือกที่จะเก็บอ้างอิงถึงมุมมองของคุณไปรอบ ๆให้แน่ใจว่าพวกเขาด้วยการยกตัวอย่างและให้แน่ใจว่าแต่ละชุดการอ้างอิงถึงโมฆะในgetApplicationContext()
onDestroy
เห็นได้ชัดว่าการรั่วไหลActivity
(ที่แขวนอยู่บนมันหลังจากที่มีการถูกทำลาย) เป็นสิ้นเปลือง .. :)
android:id
เพื่อใช้ในรหัสAPI 17 ที่แนะนำ View.generateViewId()
ซึ่งสร้าง ID เฉพาะ (ขอบคุณที่รับโอกาส - เปลี่ยนแปลงเพื่อชี้เรื่องนี้) *
หากViewGroup
ไม่สามารถกำหนดผ่าน XML (หรือคุณไม่ต้องการให้เป็น) คุณสามารถจอง id ผ่านทาง XML เพื่อให้แน่ใจว่ายังคงไม่ซ้ำกัน:
ที่นี่ค่า / ids.xmlกำหนดแบบกำหนดเองid
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="reservedNamedId" type="id"/>
</resources>
จากนั้นเมื่อสร้าง ViewGroup หรือ View แล้วคุณสามารถแนบ id ที่กำหนดเองได้
myViewGroup.setId(R.id.reservedNamedId);
id
ตัวอย่างที่ขัดแย้งกันเพื่อความชัดเจนของตัวอย่างที่ทำให้งงงวยให้ตรวจสอบสิ่งที่เกิดขึ้นเมื่อมีid
ความขัดแย้งเบื้องหลัง
รูปแบบ / mylayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/placeholder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
ในการจำลองข้อขัดแย้งสมมติว่าบิลบอร์ดล่าสุดของเราได้รับมอบหมายR.id.placeholder
( @+id/placeholder
) int
ค่าของ 12
..
ถัดไปMyActivity.javaกำหนดบางมุมมองเพิ่มโดยทางโปรแกรม (ผ่านรหัส):
int placeholderId = R.id.placeholder; // placeholderId==12
// returns *placeholder* which has id==12:
ViewGroup placeholder = (ViewGroup)this.findViewById(placeholderId);
for (int i=0; i<20; i++){
TextView tv = new TextView(this.getApplicationContext());
// One new TextView will also be assigned an id==12:
tv.setId(i);
placeholder.addView(tv);
}
ดังนั้นplaceholder
หนึ่งในสิ่งใหม่ของเราTextView
ทั้งคู่ก็มีid
12 ข้อ! แต่นี่ไม่ใช่ปัญหาจริง ๆ หากเราค้นหามุมมองย่อยของตัวยึดตำแหน่ง:
// Will return a generated TextView:
placeholder.findViewById(12);
// Whereas this will return the ViewGroup *placeholder*;
// as long as its R.id remains 12:
Activity.this.findViewById(12);
*ไม่ได้เลวร้าย
findViewById
จะทำการสำรวจเชิงลึกครั้งแรกดังนั้น "ตราบใดที่ไม่มีรหัสที่กำหนดรหัสไว้เหนือรหัสที่กำหนดโดย XML ในลำดับชั้น" ไม่ถูกต้องทางเทคนิค มันคือ "ก่อนหน้า" มากกว่า "ด้านบน"
ids.xml
ที่ว่าทำไมรหัสที่กำหนดเองที่จะต้องมีการกำหนดไว้ใน สำหรับ ID โดยพลการอย่างแท้จริงให้ใช้View.generateViewId()
(API 17) (โปรดอธิบายประเด็นของคุณหากฉันพลาด)
PreferenceDialogFragmentCompat
ดูเหมือนว่ารหัสจากR.id
ไม่ตรงกับลำดับชั้นการดู วิธีนี้ฉันไม่พบมุมมองตาม ID
คุณสามารถใช้View.setId(integer)
สำหรับสิ่งนี้ ใน XML แม้ว่าคุณจะตั้งค่า String id แต่สิ่งนี้จะถูกแปลงเป็นจำนวนเต็ม เนื่องจากสิ่งนี้คุณสามารถใช้จำนวนเต็มบวก (บวก) ใด ๆ สำหรับViews
คุณเพิ่มโดยทางโปรแกรม
ตาม
View
เอกสารประกอบตัวระบุไม่จำเป็นต้องไม่ซ้ำกันในลำดับชั้นของมุมมองนี้ ตัวระบุควรเป็นจำนวนบวก
ดังนั้นคุณสามารถใช้จำนวนเต็มบวกใด ๆ ที่คุณชอบ แต่ในกรณีนี้อาจมีบางมุมมองที่มี id เทียบเท่า หากคุณต้องการค้นหามุมมองบางอย่างในลำดับชั้นการโทรไปยัง setTag ด้วยวัตถุสำคัญบางอย่างอาจมีประโยชน์
ให้เครดิตกับคำตอบนี้
ใช่คุณสามารถโทรsetId(value)
ในมุมมองใด ๆ กับใด ๆ (บวก) findViewById(value)
ค่าจำนวนเต็มที่คุณชอบแล้วพบว่ามันในภาชนะแม่ใช้ โปรดทราบว่ามันถูกต้องในการโทรsetId()
ด้วยค่าเดียวกันสำหรับมุมมองพี่น้องที่แตกต่างกัน แต่findViewById()
จะส่งกลับเฉพาะมุมมองแรกเท่านั้น
findViewById
บรรพบุรุษที่รู้จักเป็นความคิดที่ดีสำหรับเหตุผลด้านประสิทธิภาพ แต่ก็ไม่รับประกันว่าจะพบเด็กคนหนึ่งทันทีหากมี ID ที่ถูกต้อง