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

Thử cách dùng 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 phát hành nhiều tiện ích nhằm cung cấp các phần tử tương tác nhỏ, có thể sử dụng lại, 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ù bạn có thể tạo 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 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 tệp XML mới và xác định bố cục bạn muốn sử dụng lại được. 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 từng bố cục mà bạn định thêm bố cục này.

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>, cũng phải ghi đè android:layout_heightandroid:layout_width để làm cho 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 sử dụng lại trong nhiều bố cục, thì bố cục có thể sử dụng lại khi 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 (sử dụng thẻ <include>), hệ thống sẽ bỏ qua phần tử <merge> và đặt 2 nút trực tiếp trong bố cục, thay cho thẻ <include>.

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