วิธีระบุ id เมื่อใช้รวมในไฟล์ xml เค้าโครง


117

ในไฟล์ xml เลย์เอาต์ของฉันฉันได้รวมไฟล์ xml เลย์เอาต์อื่น ๆ ไว้ด้วย (แต่ละไฟล์มี id android ที่แตกต่างกัน)

<include layout="@layout/view_contact_name" android:id="+id/test1"/>
<include layout="@layout/view_contact_name" android:id="+id/test2"/>

แต่เมื่อฉันเรียกใช้ในโปรแกรมจำลองและเริ่ม Hierarchy Viewer แต่ละเลย์เอาต์ยังคงแสดง 'NO_ID' และในโค้ดของฉันฉันมี findViewById(R.id.test1)และfindViewById(R.id.test2)ทั้งสองส่งกลับค่า null

ใครสามารถช่วยฉันแก้ปัญหาของฉัน?


6
รหัสของคุณไม่มี@สัญลักษณ์
AutonomousApps

คำตอบ:


288

ระบุ ID ในไฟล์ <include>

<include layout="@layout/test" android:id="@+id/test1" />

จากนั้นใช้สองfindViewByIdช่องเพื่อเข้าถึงฟิลด์ในเค้าโครง

View test1View = findViewById(R.id.test1);
TextView test1TextView = (TextView) test1View.findViewById(R.id.text);

เมื่อใช้แนวทางดังกล่าวคุณสามารถเข้าถึงฟิลด์ใดก็ได้ในการรวมที่คุณมี


18
วิธีนี้ส่งคืนค่า null ให้ฉันสำหรับวัตถุ test1View
Nirav Shah

4
ฉันไม่เห็นความแตกต่างจริงๆคุณอธิบายได้ไหม?
Goddchen

30
ฉันพบว่าหากเค้าโครงที่เรารวมไว้นั้นใช้การผสานสิ่งนี้จะไม่ช่วยอะไร แต่ในกรณีที่ไม่ได้ใช้การผสานจะใช้งานได้
Zlatko

@Zlatko ใช่และสิ่งนี้ไม่สามารถใช้ได้mergeแม้ในทางทฤษฎีเพราะผลของการรวม a mergeไม่ใช่มุมมองเดียว แต่เป็นกลุ่มของพวกเขา ก็โอเค
ชื่อที่แสดง

1
สิ่งนี้จะใช้ได้เฉพาะในกรณีที่ไม่ได้ใช้การผสาน ในกรณีของการรวมจะไม่สามารถทำได้ตามที่ระบุไว้ที่นี่: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed

61

ฉันพบว่าหากคุณใช้<merge>แท็กในเค้าโครงรวมของคุณรหัสของการรวมจะโอนไปยังแท็กผสานซึ่งไม่ใช่มุมมองจริง

ดังนั้นให้ลบการผสานหรือแทนที่ด้วยเค้าโครงบางส่วน

Tor Norbye เขียนว่า :

<include>แท็กไม่ได้เป็นมุมมองจริงดังนั้น findByView จะไม่พบมัน แอตทริบิวต์ @id (และแอตทริบิวต์อื่น ๆ ที่คุณตั้งค่าไว้ในแท็กรวม) จะถูกนำไปใช้กับแท็กรากของโครงร่างที่รวมไว้แทน ดังนั้น activity.getView (R.id.included1) ของคุณควรเป็น<TextView>ตัวของมันเอง


3
สิ่งที่ดี. ฉันลบแท็กผสานและเริ่มใช้งานได้ แต่คำถามของฉันที่นี่คือการใช้แท็กผสานคืออะไรหากมีเลย์เอาต์รวมที่ใช้งานได้โดยไม่มี
Ankur Chaudhary

35

Romain Guy ระบุว่าคุณสามารถแทนที่ ID ของเค้าโครงที่รวมไว้ได้โดยใส่android:idแอตทริบิวต์ไว้ใน<include>แท็ก

<include android:id="@+id/cell1" layout="@layout/workspace_screen" />

1
นี่ถูกต้องแล้ว วิธีอ้างอิงอิลิเมนต์รูทในไฟล์เลย์เอาต์ที่รวมไว้คือ id ที่ระบุในแท็ก "รวม" (เว้นแต่จะไม่ได้ระบุไว้)
ทอมอาร์

1
ID ใน <include> = ID ของ root ในรูปแบบที่รวม
Fadils

สำหรับฉันดูเหมือนว่าฉันจะตั้งค่า id ก่อน (ในแท็กรวมมันจะแทนที่ id จากเลย์เอาต์ที่รวมใช่ไหม) ฉันจะให้แท็กรวมเป็น '@ + id / cell1' ในตอนแรกแล้วตามด้วย layout = ' @ layout / workspace_screen 'จะแทนที่ android: id อีกครั้งด้วย id ของเค้าโครงที่รวมอยู่ คำตอบของ @Ron Romero เหมาะสมกับฉันมากขึ้น
Neon Warge

14

ฉันคิดว่าคำตอบยอดนิยมพลาดประเด็นที่สำคัญที่สุดและอาจทำให้ผู้คนเข้าใจผิดคิดว่า<include/>แท็กสร้างมุมมองที่เก็บเนื้อหารวมไว้

ประเด็นสำคัญคือidของ include จะถูกส่งไปยังมุมมองรูทของไฟล์เค้าโครงของ include

หมายความว่าสิ่งนี้:

// activity_main.xml
<include layout="@layout/somelayout" android:id="@+id/someid"/>

// somelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

กลายเป็นสิ่งนี้:

// activity_main.xml
<ImageView
    android:id="@+id/someid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

4

ใช่เป็นแบบนี้ แต่ระวังเมื่อเลย์เอาต์ที่แทรกในฟิลด์รวมเป็นแบบกำหนดเองและคุณต้องการเข้าถึงเค้าโครงรูทนั้น เลย์เอาต์นั้นในกรณีนี้ @ layout / test จะถูกส่งกลับในบรรทัดแรก

test test1View = (test)findViewById(R.id.test1);


2

ปัญหาคือเราพยายามใช้ id ซึ่งไม่ได้ประกาศในไฟล์เลย์เอาต์ปัจจุบัน แทนการประกาศอีกครั้ง ID @+id/สามารถเรียกว่าเพียงแค่ใช้ หากคุณ refactor ชื่อรหัสเดิมผ่าน Android Studio จะทำการ refactor ในรูปแบบที่รวมไว้ด้วยเช่นกัน

<include layout="@layout/toolbar"/>

<TextView
    android:id="@+id/txt_description"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    **android:layout_below="@+id/toolbar"**
    android:layout_marginTop="16dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"/>

2

ในกรณีของการใช้<RecyclerView>ค้นหารหัสของ<include>โดยใช้ตัวอย่างของมุมมองที่สูงเกินจริงหรือที่อื่นก็จะกลับnull

public class ViewHolder extends RecyclerView.ViewHolder {

        private mTextView;

        public ViewHolder(View view) {
            super(view);
            View include_1 = view.findViewById(R.id.include_1);
            mTextView = (TextView) include_1.findViewById(R.id.text_id);
        }
    }

1

หากคุณตั้งค่า id เป็นแท็กรูทของเลย์เอาต์ที่รวมอยู่คุณสามารถใช้ id นั้นหรือคุณสามารถตั้งค่า id เป็นเลย์เอาต์ที่รวม

แต่คุณไม่สามารถตั้งค่า id เป็นทั้งสองได้อาจทำให้เกิดข้อยกเว้นได้

<include layout="@layout/view_contact_name" android:id="+id/test1"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>

หรือ

<include layout="@layout/view_contact_name"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:id="@+id/llBottomMainView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>

0

เมื่อพูดถึงการรวมคุณจะมี id ในมุมมองรูทภายในไฟล์เลย์เอาต์ที่รวมอยู่หรือในบรรทัดรวมเองและไม่ได้อยู่ในทั้งสองอย่าง ตัวอย่างเช่น:

<include layout="@layout/layout1" android:id="@+id/layout1"/>

เค้าโครง 1 ไฟล์

<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout2">

</RelativeLayout>

ตัวอย่างข้างต้นไม่ถูกต้องเนื่องจากในทางเทคนิคคุณมีรหัสสองรายการที่ประกาศไว้สำหรับรูปแบบเดียวกัน ดังนั้นสิ่งที่คุณต้องทำคือเลือกองค์ประกอบที่จะมี id


0

ว้าวไม่น่าเชื่อว่าคำถามนี้ยังไม่มีคำตอบที่ถูกต้อง แท็กง่ายๆมันห่วย คุณสามารถเปลี่ยนได้เฉพาะสิ่งที่ขึ้นต้นด้วยandroid:layout_ซึ่งandroid:idไม่ตรงกันเท่านั้น ดังนั้นคำตอบคือคุณทำไม่ได้ ขอโทษ สิ่งที่คุณสามารถทำได้คือสร้างคลาสที่จะเป็น ViewGroup ซึ่งจะขยายมุมมองที่รวมอยู่ภายในจากนั้นเพิ่มเป็นแท็กในเค้าโครงของคุณ แต่ก็เกี่ยวกับมัน

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