Bản xem trước tiện ích được tạo cho phép bạn tạo bản xem trước linh động, phù hợp với từng cá nhân cho các tiện ích của mình, phản ánh chính xác cách các tiện ích đó sẽ xuất hiện trên màn hình chính của người dùng. Các thông tin này được cung cấp thông qua một API truyền dữ liệu, tức là ứng dụng của bạn cung cấp bản xem trước tại bất kỳ thời điểm nào trong vòng đời của ứng dụng mà không nhận được yêu cầu rõ ràng nào từ máy chủ lưu trữ tiện ích.
Để cải thiện trải nghiệm của trình chọn tiện ích trong ứng dụng, hãy cung cấp bản xem trước tiện ích được tạo trên các thiết bị Android 15 trở lên, bản xem trước tiện ích được chia tỷ lệ (bằng cách chỉ định previewLayout
) cho các thiết bị Android 12 đến Android 14 và previewImage
cho các phiên bản trước đó.
Để biết thêm thông tin, hãy xem video Làm phong phú ứng dụng bằng các bản cập nhật trực tiếp và tiện ích trên YouTube.
Thiết lập ứng dụng để xem trước tiện ích được tạo
Để hiện Bản xem trước tiện ích được tạo trên thiết bị Android 15 trở lên, trước tiên, hãy đặt giá trị compileSdk
thành 35 trở lên trong tệp build.gradle
của mô-đun để có thể cung cấp RemoteViews
cho bộ chọn tiện ích
Sau đó, các ứng dụng có thể sử dụng setWidgetPreview
trong GlanceAppWidgetManager
hoặc AppWidgetManager
. Để ngăn chặn hành vi sai trái và giảm thiểu các vấn đề về tình trạng hệ thống, setWidgetPreview
là một API bị giới hạn số lượng yêu cầu. Hạn mức mặc định là khoảng 2 lệnh gọi mỗi giờ.
Tạo bản xem trước mới bằng Jetpack Glance
Đối với các tiện ích được tạo bằng Jetpack Glance, hãy làm như sau:
Ghi đè hàm
GlanceAppWidget.providePreview
để cung cấp nội dung có khả năng kết hợp cho bản xem trước. Như bạn sẽ làm trongprovideGlance
, hãy tải dữ liệu của ứng dụng và truyền dữ liệu đó đến thành phần kết hợp nội dung của tiện ích để đảm bảo bản xem trước cho thấy dữ liệu chính xác. Không giống nhưprovideGlance
, đây là một thành phần duy nhất, không có thành phần kết hợp lại hoặc hiệu ứng.Gọi
GlanceAppWidgetManager.setWidgetPreviews
để tạo và xuất bản bản xem trước.
Không có lệnh gọi lại từ hệ thống để cung cấp bản xem trước, vì vậy, ứng dụng của bạn phải quyết định thời điểm gọi setWidgetPreviews
. Chiến lược cập nhật phụ thuộc vào trường hợp sử dụng của tiện ích:
- Nếu tiện ích có thông tin tĩnh hoặc là một thao tác nhanh, hãy đặt bản xem trước khi ứng dụng được khởi chạy lần đầu.
- Bạn có thể đặt bản xem trước sau khi ứng dụng có dữ liệu; ví dụ: sau khi người dùng đăng nhập hoặc thiết lập ban đầu.
- Bạn có thể thiết lập một tác vụ định kỳ để cập nhật bản xem trước theo nhịp độ đã chọn.
Khắc phục sự cố với bản xem trước được tạo
Một vấn đề thường gặp là sau khi bạn tạo bản xem trước, hình ảnh, biểu tượng hoặc các thành phần kết hợp khác có thể bị thiếu trong hình ảnh xem trước, so với kích thước thả của tiện ích. Kích thước thả này được xác định bằng targetCellWidth
và targetCellHeight
(nếu được chỉ định) hoặc bằng minWidth
và minHeight
trong tệp thông tin của nhà cung cấp tiện ích ứng dụng.
Điều này xảy ra vì theo mặc định, Android chỉ kết xuất những thành phần kết hợp hiển thị ở kích thước tối thiểu của tiện ích. Nói cách khác, theo mặc định, Android sẽ đặt previewSizeMode
thành SizeMode.Single
. Thao tác này sử dụng android:minHeight
và android:minWidth
trong XML thông tin về trình cung cấp tiện ích ứng dụng để xác định thành phần kết hợp nào cần vẽ.
Để khắc phục vấn đề này, hãy ghi đè previewSizeMode
trong GlanceAppWidget
và đặt thành SizeMode.Responsive
, cung cấp một tập hợp các giá trị DpSize
. Thao tác này cho Android biết tất cả các kích thước bố cục cần thiết để hiển thị bản xem trước, đảm bảo tất cả các phần tử đều hiển thị chính xác.
Tối ưu hoá cho các hệ số hình dạng cụ thể. Cung cấp 1 hoặc 2 kích thước bắt đầu từ kích thước tối thiểu và tuân theo các điểm ngắt của tiện ích. Chỉ định ít nhất một hình ảnh để đảm bảo khả năng tương thích ngược. Bạn có thể tìm thấy các giá trị DP tối thiểu phù hợp cho nhiều kích thước lưới trong hướng dẫn thiết kế tiện ích.
Tạo bản xem trước mới mà không cần Jetpack Glance
Bạn có thể dùng RemoteViews
mà không cần chế độ Xem nhanh. Ví dụ sau đây tải một tài nguyên bố cục tiện ích XML và đặt tài nguyên đó làm bản xem trước. Bạn phải có chế độ cài đặt bản dựng compileSdk từ 35 trở lên để setWidgetPreview
xuất hiện dưới dạng một phương thức trong đoạn mã này.
AppWidgetManager.getInstance(appContext).setWidgetPreview(
ComponentName(
appContext,
ExampleAppWidgetReceiver::class.java
),
AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
RemoteViews("com.example", R.layout.widget_preview)
)
Thêm bản xem trước tiện ích có thể mở rộng vào bộ chọn tiện ích
Kể từ Android 12, bản xem trước tiện ích xuất hiện trong bộ chọn tiện ích có thể điều chỉnh quy mô. Bạn cung cấp bố cục này dưới dạng một bố cục XML được đặt thành kích thước mặc định của tiện ích. Trước đây, bản xem trước tiện ích là một tài nguyên có thể vẽ tĩnh, trong một số trường hợp, điều này dẫn đến việc bản xem trước phản ánh không chính xác cách tiện ích xuất hiện khi được thêm vào màn hình chính.
Để triển khai bản xem trước tiện ích có thể mở rộng, hãy sử dụng thuộc tính previewLayout
của phần tử appwidget-provider
để cung cấp một bố cục XML thay thế:
<appwidget-provider
android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
Bạn nên sử dụng cùng một bố cục như tiện ích thực tế, với các giá trị mặc định hoặc giá trị kiểm thử thực tế. Hầu hết các ứng dụng đều dùng cùng một previewLayout
và initialLayout
. Để được hướng dẫn về cách tạo bố cục xem trước chính xác, hãy xem phần sau đây trên trang này.
Bạn nên chỉ định cả thuộc tính previewLayout
và previewImage
để ứng dụng của bạn có thể quay lại sử dụng previewImage
nếu thiết bị của người dùng không hỗ trợ previewLayout
. Thuộc tính previewLayout
được ưu tiên hơn thuộc tính previewImage
.
Khả năng tương thích ngược với bản xem trước tiện ích
Để cho phép các bộ chọn tiện ích trên Android 11 (API cấp 30) trở xuống hiển thị bản xem trước tiện ích của bạn hoặc làm phương án dự phòng cho Bản xem trước đã tạo, hãy chỉ định thuộc tính previewImage
.
Nếu bạn thay đổi giao diện của tiện ích, hãy cập nhật hình ảnh xem trước.
Tạo bản xem trước chính xác có chứa các mục động

Phần này giải thích phương pháp được đề xuất để hiển thị nhiều mục trong bản xem trước của tiện ích cho một tiện ích có khung hiển thị tập hợp, tức là một tiện ích sử dụng ListView
, GridView
hoặc StackView
. Điều này không áp dụng cho bản xem trước tiện ích được tạo.
Nếu tiện ích của bạn dùng một trong các khung hiển thị này, thì việc tạo bản xem trước có thể mở rộng bằng cách cung cấp trực tiếp bố cục tiện ích thực tế sẽ làm giảm trải nghiệm khi bản xem trước tiện ích không hiển thị mục nào. Điều này xảy ra vì dữ liệu của khung hiển thị bộ sưu tập được đặt động trong thời gian chạy và trông tương tự như hình ảnh trong hình 1.
Để bản xem trước của các tiện ích có khung hiển thị tập hợp hiển thị đúng cách trong bộ chọn tiện ích, bạn nên duy trì một tệp bố cục riêng biệt chỉ dành cho bản xem trước. Tệp bố cục riêng biệt này phải bao gồm những nội dung sau:
- Bố cục thực tế của tiện ích.
- Một khung hiển thị tập hợp phần giữ chỗ có các mục giả. Ví dụ: bạn có thể mô phỏng một
ListView
bằng cách cung cấp một phần giữ chỗLinearLayout
với một số mục danh sách giả.
Để minh hoạ ví dụ về ListView
, hãy bắt đầu bằng một tệp bố cục riêng biệt:
// res/layout/widget_preview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/widget_background"
android:orientation="vertical">
// Include the actual widget layout that contains ListView.
<include
layout="@layout/widget_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
// The number of fake items you include depends on the values you provide
// for minHeight or targetCellHeight in the AppWidgetProviderInfo
// definition.
<TextView android:text="@string/fake_item1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
<TextView android:text="@string/fake_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
</LinearLayout>
Chỉ định tệp bố cục xem trước khi cung cấp thuộc tính previewLayout
của siêu dữ liệu AppWidgetProviderInfo
. Bạn vẫn chỉ định bố cục tiện ích thực tế cho thuộc tính initialLayout
và sử dụng bố cục tiện ích thực tế khi tạo RemoteViews
trong thời gian chạy.
<appwidget-provider
previewLayout="@layout/widget_previe"
initialLayout="@layout/widget_view" />
Các mục phức tạp trong danh sách
Ví dụ trong phần trước cung cấp các mục giả trong danh sách, vì các mục trong danh sách là các đối tượng TextView
. Việc cung cấp các mục giả có thể phức tạp hơn nếu các mục đó là bố cục phức tạp.
Hãy xem xét một mục trong danh sách được xác định trong widget_list_item.xml
và bao gồm 2 đối tượng TextView
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_title" />
<TextView android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_content" />
</LinearLayout>
Để cung cấp các mục giả trong danh sách, bạn có thể thêm bố cục nhiều lần, nhưng điều này khiến mỗi mục trong danh sách đều giống hệt nhau. Để cung cấp các mục duy nhất trong danh sách, hãy làm theo các bước sau:
Tạo một nhóm thuộc tính cho các giá trị văn bản:
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>
Hãy sử dụng các thuộc tính này để đặt văn bản:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetTitle" /> <TextView android:id="@id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetContent" /> </LinearLayout>
Tạo bao nhiêu kiểu tuỳ ý cho bản xem trước. Xác định lại các giá trị trong từng kiểu:
<resources> <style name="Theme.Widget.ListItem"> <item name="widgetTitle"></item> <item name="widgetContent"></item> </style> <style name="Theme.Widget.ListItem.Preview1"> <item name="widgetTitle">Fake Title 1</item> <item name="widgetContent">Fake content 1</item> </style> <style name="Theme.Widget.ListItem.Preview2"> <item name="widgetTitle">Fake title 2</item> <item name="widgetContent">Fake content 2</item> </style> </resources>
Áp dụng các kiểu cho các mục giả trong bố cục xem trước:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" ...> <include layout="@layout/widget_view" ... /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview1" /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview2" /> </LinearLayout>