Sử dụng lại bố cục với <include>

Thử cách Compose
Jetpack Compose là bộ công cụ giao diện người dùng được đề xuất cho Android. Tìm hiểu cách sử dụng bố cục trong ứng dụng Compose.

Mặc dù Android cung cấp nhiều tiện ích để cung cấp các phần tử nhỏ, có thể sử dụng lại và có tính tương tác, nhưng bạn cũng có thể cần dùng lại các thành phần lớn hơn yêu cầu bố cục đặc biệt. Để sử dụng lại một cách hiệu quả các bố cục hoàn chỉnh, hãy sử dụng các thẻ <include><merge> để nhúng một bố cục bên trong một bố cục khác.

Điều này cho phép bạn tạo các bố cục phức tạp, chẳng hạn như bảng điều khiển nút có hoặc không hoặc thanh tiến trình tuỳ chỉnh có văn bản mô tả. Điều này có nghĩa là bạn có thể trích xuất mọi phần tử trong ứng dụng phổ biến trên nhiều bố cục, quản lý riêng các phần tử đó và đưa các phần tử đó vào từng bố cục. Mặc dù tạo được các thành phần giao diện người dùng riêng lẻ bằng cách viết một View tuỳ chỉnh, nhưng bạn có thể thực hiện việc này dễ dàng hơn nữa bằng cách sử dụng lại tệp bố cục.

Tạo bố cục có thể sử dụng lại

Bắt đầu bằng cách tạo một tệp XML mới và xác định bố cục mà bạn muốn sử dụng lại. Ví dụ: đây là bố cục xác định thanh tiêu đề sẽ được đưa vào mỗi hoạt động (titlebar.xml):

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/titlebar_bg"
    tools:showIn="@layout/activity_main" >

    <ImageView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:src="@drawable/gafricalogo" />
</FrameLayout>

View gốc phải đúng như cách bạn muốn nó xuất hiện trong mỗi bố cục mà bạn dự định thêm bố cục này vào.

Sử dụng thẻ <include>

Bên trong bố cục mà bạn muốn thêm thành phần có thể sử dụng lại, hãy thêm thẻ <include>. Ví dụ: dưới đây là một bố cục bao gồm thanh tiêu đề trong ví dụ trước:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/app_bg"
    android:gravity="center_horizontal">

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

    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:text="@string/hello"
              android:padding="10dp" />
    ...
</LinearLayout>

Bạn cũng có thể ghi đè tất cả tham số bố cục (bất kỳ thuộc tính android:layout_* nào) của khung hiển thị gốc thuộc bố cục đi kèm bằng cách chỉ định các tham số này trong thẻ <include>. Lệnh này được minh hoạ trong ví dụ sau:

<include android:id="@+id/news_title"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         layout="@layout/title"/>

Tuy nhiên, nếu bạn muốn ghi đè thuộc tính bố cục bằng thẻ <include>, hãy ghi đè cả android:layout_heightandroid:layout_width để các thuộc tính bố cục khác có hiệu lực.

Sử dụng thẻ <merge>

Thẻ <merge> giúp loại bỏ các nhóm khung hiển thị thừa trong hệ phân cấp khung hiển thị khi đưa một bố cục vào một bố cục khác. Một trường hợp sử dụng <merge> là khi bạn triển khai một thành phần hiển thị tuỳ chỉnh bằng cách mở rộng ViewGroup.

Ví dụ: nếu bố cục chính của bạn là LinearLayout dọc, trong đó 2 khung hiển thị liên tiếp có thể được dùng lại trong nhiều bố cục, thì bố cục có thể sử dụng lại mà bạn đặt 2 khung hiển thị sẽ yêu cầu khung hiển thị gốc riêng. Tuy nhiên, việc sử dụng một LinearLayout khác làm gốc cho bố cục có thể sử dụng lại sẽ dẫn đến việc một LinearLayout dọc nằm bên trong một LinearLayout dọc. LinearLayout được lồng không có mục đích thực tế nào và làm chậm hiệu suất giao diện người dùng.

Thay vào đó, bạn có thể mở rộng LinearLayout để tạo một thành phần hiển thị tuỳ chỉnh và sử dụng XML bố cục để mô tả các thành phần hiển thị con của thành phần hiển thị đó. Thẻ trên cùng trong XML là <merge>, thay vì LinearLayout, như trong ví dụ sau:

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/delete"/>

</merge>

Khi bạn đưa bố cục này vào một bố cục khác (bằng thẻ <include>), hệ thống sẽ bỏ qua phần tử <merge> và đặt hai nút trực tiếp vào bố cục đó, thay cho thẻ <include>.

Để biết thêm thông tin về <include>, hãy xem phần Tài nguyên bố cục.