ในไฟล์ 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 ที่กำหนดโดยViews ที่สร้างโดยInflater(เช่นโดยใช้setContentView)
idผ่านXMLandroid: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จะไม่ซ้ำกันids ทำไม่ได้จะต้องไม่ซ้ำกันids สามารถ (ทฤษฎี) ความขัดแย้งกับXML-assigned idsids จะไม่ว่าถ้าถามอย่างถูกต้อง(อ่านเก็บ)idไม่สำคัญfindViewById(int)จะย้ำความลึกแรกซ้ำผ่านลำดับชั้นดูจากมุมมองที่คุณระบุและกลับคนแรกที่จะพบกับการจับคู่Viewididก่อนที่ XML จะถูกกำหนดidในลำดับชั้นfindViewById(R.id.somename)จะส่งคืนมุมมองที่กำหนดโดย XML ดังนั้นid'dIDsViewGroupidLinearLayoutandroid:id="@+id/placeholder"ViewGroupด้วยViewsidที่สะดวกสำหรับแต่ละมุมมองเคียวรีมุมมองชายด์เหล่านี้โดยใช้ 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ทั้งคู่ก็มีid12 ข้อ! แต่นี่ไม่ใช่ปัญหาจริง ๆ หากเราค้นหามุมมองย่อยของตัวยึดตำแหน่ง:
// 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 ที่ถูกต้อง