Cách chỉ định id khi sử dụng bao gồm trong tệp xml bố cục


117

Trong tệp xml bố cục của tôi, tôi đã bao gồm tệp xml bố cục khác (mỗi tệp có một id android khác nhau).

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

Nhưng khi tôi chạy nó trong trình mô phỏng và khởi động Trình xem phân cấp, mỗi bố cục vẫn hiển thị 'NO_ID' và trong mã của tôi, tôi có findViewById(R.id.test1)findViewById(R.id.test2)cả hai đều trả về null.

Bất cứ ai có thể vui lòng giúp tôi với vấn đề của tôi?


6
ID của bạn thiếu @ký hiệu.
AutonomousApps

Câu trả lời:


288

Chỉ định ID trong <include>

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

Sau đó, sử dụng hai findViewByIdđể truy cập các trường trong bố cục

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

Sử dụng cách tiếp cận đó, bạn có thể truy cập bất kỳ trường nào trong bất kỳ trường nào bạn có.


18
Phương thức này trả về cho tôi giá trị null cho đối tượng test1View.
Nirav Shah

4
Tôi không thực sự thấy sự khác biệt, bạn có thể giải thích?
Goddchen

30
Tôi phát hiện ra rằng nếu bố cục mà chúng tôi đưa vào đang sử dụng hợp nhất, điều này sẽ không hữu ích. Nhưng trong trường hợp hợp nhất không được sử dụng, điều này sẽ hoạt động.
Zlatko

@Zlatko Yep, và điều này không thể hoạt động mergengay cả trên lý thuyết, bởi vì kết quả của việc bao gồm một mergelượt xem không phải là một lượt xem mà là một loạt các lượt xem. Vậy là được.
Tên hiển thị

1
Điều này sẽ chỉ hoạt động trong trường hợp hợp nhất không được sử dụng. Trong trường hợp hợp nhất nó không thể như quy định ở đây: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed

61

Tôi phát hiện ra rằng nếu bạn đang sử dụng <merge>thẻ trong bố cục bao gồm của mình, thì ID của bao gồm chuyển sang thẻ hợp nhất không phải là chế độ xem thực.

Vì vậy, xóa hợp nhất hoặc thay thế nó bằng một số bố cục.

Tor Norbye viết :

Các <include>thẻ không phải là một cái nhìn thực tế, do findByView sẽ không tìm thấy nó. Thay vào đó, thuộc tính @id (và bất kỳ thuộc tính nào khác mà bạn đã đặt trên thẻ bao gồm) được áp dụng trên thẻ gốc của bố cục được bao gồm. Vì vậy, Activity.getView (R.id.included1) của bạn trên thực tế phải là <TextView>chính nó.


3
Tốt. Tôi xóa thẻ hợp nhất và nó bắt đầu hoạt động nhưng câu hỏi của tôi ở đây là việc sử dụng thẻ hợp nhất là gì nếu có bố cục bao gồm hoạt động mà không có nó?
Ankur Chaudhary

35

Romain Guy chỉ ra rằng bạn có thể ghi đè ID của một bố cục được bao gồm bằng cách đặt một android:idthuộc tính bên trong <include>thẻ.

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

1
Chính xác. Cách để tham chiếu đến phần tử gốc trong tệp bố cục được bao gồm là bằng id được cung cấp trong thẻ 'bao gồm' (trừ khi nó không được cung cấp).
Tom R

1
ID trong <include> = root's ID trong bố cục được bao gồm
Fadils

Tôi thấy có vẻ như nếu tôi đặt id trước (trong thẻ include, nó sẽ ghi đè id từ bố cục được bao gồm, phải không?), Tôi sẽ có thẻ bao gồm ban đầu là '@ + id / cell1' và sau đó là layout = ' @ layout / workspace_screen 'sẽ ghi đè lại android: id bằng id của bố cục được bao gồm. Câu trả lời của @Ron Romero có ý nghĩa hơn đối với tôi.
Neon Warge

14

Tôi nghĩ rằng câu trả lời hàng đầu bỏ lỡ điểm quan trọng nhất và có thể khiến mọi người hiểu nhầm rằng <include/>thẻ tạo Chế độ xem chứa nội dung bao gồm.

Điểm quan trọng là id của include được chuyển đến chế độ xem gốc của tệp bố cục của include.

Có nghĩa là điều này:

// 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"
    />

Trở thành cái này:

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

4

vâng là như thế này, nhưng hãy cẩn thận khi bố cục được chèn trong trường bao gồm là một bố cục tùy chỉnh và bạn muốn truy cập bố cục gốc đó. Bố cục đó trong trường hợp này là @ layout / test test, thực sự được trả về ở dòng đầu tiên.

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


2

Vấn đề là chúng tôi cố gắng sử dụng id không được khai báo trong tệp bố cục hiện tại. Thay vì khai báo lại, id có thể được tham chiếu đơn giản bằng cách sử dụng @+id/. Nếu bạn cấu trúc lại tên id ban đầu thông qua Android Studio, nó cũng sẽ cấu trúc lại trong bố cục bao gồm.

<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

Trong trường hợp sử dụng, <RecyclerView>hãy tìm id của <include>bằng cách sử dụng một thể hiện của chế độ xem được thổi phồng, nếu không nó sẽ trả về 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

Nếu bạn đã đặt id thành một trong hai thẻ gốc của bố cục được bao gồm thì bạn có thể sử dụng id đó hoặc bạn có thể đặt id cho bố cục được bao gồm.

Nhưng bạn không thể đặt id cho cả hai, nó có thể ném ra ngoại lệ.

<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>

Hoặc là

<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

Khi nói về bao gồm, bạn có một id trên chế độ xem gốc bên trong tệp bố cục được bao gồm hoặc trên chính dòng bao gồm và không có trên cả hai. Ví dụ:

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

Bố cục 1 tệp

<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>

Ví dụ trên là sai vì về mặt kỹ thuật, bạn có hai id được khai báo cho cùng một bố cục. Vì vậy, những gì bạn phải làm là chọn phần tử nào sẽ có id.


0

Wow, tôi không thể tin rằng câu hỏi này vẫn chưa có câu trả lời chính xác. Các thẻ đơn giản thật tệ. Bạn chỉ có thể thay đổi mọi thứ bắt đầu bằng android:layout_android:idkhông phù hợp. Vì vậy, câu trả lời là bạn không thể. Lấy làm tiếc. Thay vào đó, những gì bạn có thể làm là tạo một lớp sẽ là một ViewGroup sẽ thổi phồng các chế độ xem được bao gồm bên trong, sau đó thêm nó làm thẻ trong bố cục của bạn, nhưng đó là vấn đề.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.