Tiện ích ứng dụng là các chế độ xem ứng dụng thu nhỏ mà bạn có thể nhúng vào các chế độ xem khác các ứng dụng—chẳng hạn như màn hình chính—và nhận bản cập nhật định kỳ. Các chế độ xem được gọi là tiện ích trong giao diện người dùng và bạn có thể xuất bản một ứng dụng có nhà cung cấp tiện ích ứng dụng (hoặc nhà cung cấp tiện ích). Một thành phần ứng dụng chứa các tiện ích khác được gọi là máy chủ tiện ích ứng dụng (hoặc máy chủ tiện ích). Hình 1 hiển thị một tiện ích nhạc mẫu:
Tài liệu này mô tả cách phát hành tiện ích bằng nhà cung cấp tiện ích. Cho
thông tin chi tiết về cách tạo AppWidgetHost
của riêng bạn để
lưu trữ tiện ích của ứng dụng, hãy xem bài viết Tạo máy chủ tiện ích.
Để biết thông tin về cách thiết kế tiện ích, hãy xem nội dung Tổng quan về tiện ích ứng dụng.
Thành phần tiện ích
Để tạo một tiện ích, bạn cần có những thành phần cơ bản sau đây:
- Đối tượng
AppWidgetProviderInfo
- Mô tả siêu dữ liệu của một tiện ích, chẳng hạn như bố cục của tiện ích, bản cập nhật
tần suất và lớp
AppWidgetProvider
.AppWidgetProviderInfo
được định nghĩa trong XML, là được mô tả trong tài liệu này. - Lớp
AppWidgetProvider
- Xác định các phương thức cơ bản cho phép bạn lập trình giao diện với
tiện ích. Thông qua đó, bạn sẽ nhận được thông báo khi tiện ích được cập nhật,
bật, tắt hoặc xoá. Bạn khai báo
AppWidgetProvider
trong tệp kê khai rồi triển khai, như được mô tả trong tài liệu này. - Xem bố cục
- Xác định bố cục ban đầu cho tiện ích. Bố cục này được xác định trong XML, như được mô tả trong tài liệu này.
Hình 2 cho thấy cách các thành phần này phù hợp với quá trình xử lý tiện ích ứng dụng tổng thể luồng.
Nếu tiện ích của bạn cần cấu hình người dùng, hãy triển khai cấu hình tiện ích ứng dụng của bạn. Hoạt động này cho phép người dùng sửa đổi các chế độ cài đặt của tiện ích (ví dụ: múi giờ cho tiện ích đồng hồ.
- Kể từ Android 12 (API cấp 31), bạn có thể cung cấp và cho phép người dùng định cấu hình lại tiện ích sau. Hãy xem bài viết Sử dụng cấu hình mặc định của tiện ích và Bật người dùng định cấu hình lại các tiện ích được đặt để biết thêm chi tiết.
- Trong Android 11 (API cấp 30) trở xuống, hoạt động này sẽ được khởi chạy mỗi lần người dùng thêm tiện ích đó vào màn hình chính.
Chúng tôi cũng đề xuất các cải tiến sau: bố cục tiện ích linh hoạt, các tính năng nâng cao khác, tiện ích nâng cao, tiện ích bộ sưu tập và tạo tiện ích .
Khai báo tệp XML AppWidgetProviderInfo
Đối tượng AppWidgetProviderInfo
xác định các tính chất thiết yếu của một tiện ích.
Xác định đối tượng AppWidgetProviderInfo
trong tệp tài nguyên XML bằng một
Phần tử <appwidget-provider>
và lưu vào thư mục res/xml/
của dự án.
Lệnh này được minh hoạ trong ví dụ sau:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:targetCellWidth="1"
android:targetCellHeight="1"
android:maxResizeWidth="250dp"
android:maxResizeHeight="120dp"
android:updatePeriodMillis="86400000"
android:description="@string/example_appwidget_description"
android:previewLayout="@layout/example_appwidget_preview"
android:initialLayout="@layout/example_loading_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>
Thuộc tính định kích thước tiện ích
Màn hình chính mặc định đặt các tiện ích trong cửa sổ dựa trên một lưới ô có chiều cao và chiều rộng xác định. Hầu hết màn hình chính chỉ cho phép các tiện ích đảm nhận kích thước là bội số nguyên của các ô lưới (ví dụ: 2 ô) theo chiều ngang với 3 ô theo chiều dọc.
Các thuộc tính kích thước tiện ích cho phép bạn chỉ định một kích thước mặc định cho tiện ích và cung cấp giới hạn dưới và giới hạn trên cho kích thước của tiện ích. Trong ngữ cảnh này, kích thước mặc định của tiện ích là kích thước mà tiện ích sẽ có khi được xuất hiện lần đầu tiên đã thêm vào màn hình chính.
Bảng sau đây mô tả các thuộc tính <appwidget-provider>
liên quan đến
đối với kích thước tiện ích:
Thuộc tính và nội dung mô tả | |
---|---|
targetCellWidth và
targetCellHeight (Android 12),
minWidth và minHeight |
targetCellWidth và
targetCellHeight , minWidth và
minHeight —để ứng dụng của bạn có thể quay lại sử dụng
minWidth và minHeight nếu thiết bị của người dùng
không hỗ trợ targetCellWidth và
targetCellHeight . Nếu được hỗ trợ,
Thuộc tính targetCellWidth và targetCellHeight
được ưu tiên hơn minWidth và minHeight
.
|
minResizeWidth và
minResizeHeight |
Chỉ định kích thước tối thiểu tuyệt đối của tiện ích. Các giá trị này chỉ định
kích thước mà tiện ích không đọc được hoặc không sử dụng được. Sử dụng
các thuộc tính này cho phép người dùng đổi kích thước tiện ích thành kích thước nhỏ hơn
so với kích thước tiện ích mặc định. Thuộc tính minResizeWidth là
sẽ bị bỏ qua nếu lớn hơn minWidth hoặc nếu giá trị này theo chiều ngang
chưa bật tính năng đổi kích thước. Xem
resizeMode . Tương tự,
Thuộc tính minResizeHeight sẽ bị bỏ qua nếu giá trị này lớn hơn
minHeight hoặc nếu tính năng đổi kích thước theo chiều dọc không được bật. |
maxResizeWidth và
maxResizeHeight |
Chỉ định kích thước tối đa được đề xuất cho tiện ích. Nếu các giá trị không giống nhau
kích thước của ô lưới được làm tròn lên giá trị gần nhất
kích thước ô. Thuộc tính maxResizeWidth sẽ bị bỏ qua nếu
nhỏ hơn minWidth hoặc nếu không đổi kích thước theo chiều ngang
bật. Hãy xem resizeMode . Tương tự,
thuộc tính maxResizeHeight sẽ bị bỏ qua nếu giá trị này lớn hơn
minHeight hoặc nếu tính năng đổi kích thước theo chiều dọc không được bật.
Ra mắt trong Android 12. |
resizeMode |
Chỉ định các quy tắc mà theo đó bạn có thể đổi kích thước tiện ích. Bạn có thể dùng
để làm cho các tiện ích trên màn hình chính có thể đổi kích thước theo chiều ngang, chiều dọc,
hoặc trên cả hai trục. Người dùng chạm & giữ một tiện ích để hiện ô điều khiển thay đổi kích thước,
sau đó kéo ô điều khiển theo chiều ngang hoặc chiều dọc để thay đổi kích thước trên
lưới bố cục. Các giá trị cho thuộc tính resizeMode bao gồm
horizontal , vertical và none . Người nhận
khai báo tiện ích là có thể đổi kích thước theo chiều ngang và chiều dọc, sử dụng
horizontal|vertical . |
Ví dụ
Để minh hoạ cách các thuộc tính trong bảng trước ảnh hưởng đến kích thước tiện ích, giả định các thông số kỹ thuật sau:
- Ô lưới có chiều rộng 30 dp và chiều cao 50 dp.
- Hệ thống cung cấp quy cách thuộc tính sau đây:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="80dp"
android:minHeight="80dp"
android:targetCellWidth="2"
android:targetCellHeight="2"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:maxResizeWidth="120dp"
android:maxResizeHeight="120dp"
android:resizeMode="horizontal|vertical" />
Kể từ Android 12:
Dùng thuộc tính targetCellWidth
và targetCellHeight
làm thuộc tính mặc định
kích thước của tiện ích.
Kích thước của tiện ích là 2x2 theo mặc định. Bạn có thể thay đổi kích thước tiện ích thành 2x1 hoặc lên đến 4x3.
Android 11 trở xuống:
Dùng thuộc tính minWidth
và minHeight
để tính toán kích thước mặc định của
tiện ích.
Chiều rộng mặc định = Math.ceil(80 / 30)
= 3
Chiều cao mặc định = Math.ceil(80 / 50)
= 2
Kích thước của tiện ích là 3x2 theo mặc định. Bạn có thể thay đổi kích thước tiện ích thành 2x1 hoặc lên chế độ toàn màn hình.
Thuộc tính tiện ích bổ sung
Bảng sau đây mô tả các thuộc tính <appwidget-provider>
liên quan đến
cho các chất lượng khác ngoài kích thước tiện ích.
Thuộc tính và nội dung mô tả | |
---|---|
updatePeriodMillis |
Xác định tần suất khung tiện ích yêu cầu cập nhật từ
AppWidgetProvider bằng cách gọi onUpdate()
phương thức gọi lại. Quá trình cập nhật thực tế không đảm bảo sẽ diễn ra chính xác vào
với giá trị này và bạn nên cập nhật ít nhất là
có thể (không quá một lần mỗi giờ) để tiết kiệm pin.
Để xem danh sách đầy đủ các yếu tố cần cân nhắc để chọn khoảng thời gian cập nhật phù hợp,
xem
Tối ưu hoá cho việc cập nhật tiện ích
. |
initialLayout |
Trỏ đến tài nguyên bố cục xác định bố cục tiện ích. |
configure |
Xác định hoạt động khởi chạy khi người dùng thêm tiện ích, cho phép họ định cấu hình các thuộc tính tiện ích. Xem Cho phép người dùng định cấu hình tiện ích. Kể từ Android 12, ứng dụng của bạn có thể bỏ qua bước đầu . Hãy xem bài viết Sử dụng cấu hình mặc định của tiện ích để biết chi tiết. |
description |
Chỉ định nội dung mô tả cho bộ chọn tiện ích mà bạn muốn hiển thị tiện ích. Ra mắt trong Android 12. |
previewLayout (Android 12)
và previewImage (Android 11 trở xuống) |
previewImage
và previewLayout để ứng dụng của bạn có thể quay lại sử dụng
sang sử dụng previewImage nếu thiết bị của người dùng không hỗ trợ
previewLayout . Để biết thêm thông tin, hãy xem
Khả năng tương thích ngược với khả năng mở rộng
bản xem trước tiện ích.
|
autoAdvanceViewId |
Chỉ định mã chế độ xem của chế độ xem phụ tiện ích được tự động nâng cao bằng máy chủ lưu trữ của tiện ích. |
widgetCategory |
Khai báo việc tiện ích của bạn có thể hiển thị trên màn hình chính hay không
(home_screen ), màn hình khoá (keyguard ) hoặc
cả hai. Đối với Android 5.0 trở lên, chỉ home_screen hợp lệ.
|
widgetFeatures |
Khai báo các tính năng mà tiện ích hỗ trợ. Ví dụ: nếu bạn muốn
tiện ích của bạn để sử dụng cấu hình mặc định khi người dùng thêm tiện ích đó, hãy chỉ định
cả
configuration_optional
và
reconfigurable
cờ. Thao tác này bỏ qua việc khởi chạy hoạt động định cấu hình sau khi người dùng
sẽ thêm tiện ích. Người dùng vẫn có thể
định cấu hình lại tiện ích
sau đó. |
Sử dụng lớp AppWidgetProvider để xử lý các thông báo truyền tin tiện ích
Lớp AppWidgetProvider
xử lý việc truyền tin và cập nhật tiện ích
nhằm phản hồi các sự kiện trong vòng đời của tiện ích. Các phần sau đây mô tả cách
khai báo AppWidgetProvider
trong tệp kê khai rồi triển khai.
Khai báo tiện ích trong tệp kê khai
Trước tiên, hãy khai báo lớp AppWidgetProvider
trong AndroidManifest.xml
của ứng dụng
như trong ví dụ sau:
<receiver android:name="ExampleAppWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
Phần tử <receiver>
cần có thuộc tính android:name
. Thuộc tính này chỉ định
AppWidgetProvider
mà tiện ích sử dụng. Không được xuất thành phần này
trừ phi có một quy trình riêng cần truyền tin đến AppWidgetProvider
của bạn.
thường không phải vậy.
Phần tử <intent-filter>
phải bao gồm một phần tử <action>
có giá trị
android:name
. Thuộc tính này chỉ định rằng AppWidgetProvider
chấp nhận
ACTION_APPWIDGET_UPDATE
truyền tin. Đây là thông báo truyền tin duy nhất mà bạn phải khai báo rõ ràng. Chiến lược phát hành đĩa đơn
AppWidgetManager
tự động gửi tất cả thông báo truyền phát tiện ích khác tới AppWidgetProvider
dưới dạng
nếu cần.
Phần tử <meta-data>
chỉ định tài nguyên AppWidgetProviderInfo
và
yêu cầu các thuộc tính sau:
android:name
: chỉ định tên của siêu dữ liệu. Sử dụngandroid.appwidget.provider
để xác định dữ liệu Phần mô tảAppWidgetProviderInfo
.android:resource
: chỉ định tài nguyênAppWidgetProviderInfo
vị trí.
Triển khai lớp AppWidgetProvider
Lớp AppWidgetProvider
mở rộng
BroadcastReceiver
với tư cách là
lớp tiện lợi để xử lý thông báo truyền tin tiện ích. Hàm này chỉ nhận được sự kiện
thông báo truyền phát liên quan đến tiện ích, chẳng hạn như khi tiện ích được cập nhật,
đã xoá, bật và tắt. Khi các sự kiện truyền phát này xảy ra, những điều sau
Các phương thức AppWidgetProvider
được gọi là:
onUpdate()
- Lệnh gọi này được gọi để cập nhật tiện ích theo các khoảng thời gian do hàm
Thuộc tính
updatePeriodMillis
trongAppWidgetProviderInfo
. Xem bảng mô tả các thuộc tính tiện ích bổ sung trong trang này cho biết thêm thông tin. - Phương thức này cũng được gọi khi người dùng thêm tiện ích, vì vậy, phương thức này thực hiện
thiết lập cần thiết, chẳng hạn như xác định trình xử lý sự kiện
Đối tượng
View
hoặc bắt đầu công việc để tải dữ liệu vào hiển thị trong tiện ích. Tuy nhiên, nếu bạn khai báo một hoạt động cấu hình không có cờconfiguration_optional
, phương thức này không được gọi khi người dùng thêm tiện ích, nhưng tiện ích được gọi cho các bản cập nhật tiếp theo. Đó là chịu trách nhiệm của hoạt động định cấu hình để thực hiện cập nhật đầu tiên khi cấu hình hoàn tất. Xem Cho phép người dùng định cấu hình tiện ích ứng dụng để biết thêm thông tin. - Lệnh gọi lại quan trọng nhất là
onUpdate()
. Hãy xem bài viết Xử lý sự kiện bằng LớponUpdate()
trên trang này để biết thêm thông tin. onAppWidgetOptionsChanged()
Lệnh này được gọi khi tiện ích được đặt lần đầu tiên và bất cứ khi nào tiện ích được đặt đã đổi kích thước. Sử dụng lệnh gọi lại này để hiện hoặc ẩn nội dung dựa trên kích thước của tiện ích dải ô. Xem phạm vi kích thước và kể từ Android 12, danh sách các kích thước có thể mà một thực thể tiện ích có thể sử dụng – bằng cách gọi
getAppWidgetOptions()
! Hàm này sẽ trả vềBundle
chứa sau:OPTION_APPWIDGET_MIN_WIDTH
: chứa giới hạn dưới trên chiều rộng, tính bằng đơn vị dp, của một phiên bản tiện ích.OPTION_APPWIDGET_MIN_HEIGHT
: chứa giới hạn dưới của chiều cao, tính bằng đơn vị dp, của một phiên bản tiện ích.OPTION_APPWIDGET_MAX_WIDTH
: chứa giới hạn trên trên chiều rộng, tính bằng đơn vị dp, của một phiên bản tiện ích.OPTION_APPWIDGET_MAX_HEIGHT
: chứa giới hạn trên của chiều cao, tính bằng đơn vị dp, của một phiên bản tiện ích.OPTION_APPWIDGET_SIZES
: chứa danh sách các kích thước có thể sử dụng (List<SizeF>
), theo đơn vị dp, mà thực thể tiện ích nào có thể thực hiện. Ra mắt trong Android 12.
onDeleted(Context, int[])
Lệnh này được gọi mỗi khi một tiện ích bị xoá khỏi máy chủ tiện ích.
onEnabled(Context)
Lệnh này được gọi khi một thực thể của tiện ích được tạo lần đầu tiên. Ví dụ: nếu người dùng thêm hai phiên bản tiện ích của bạn, thực thể này chỉ được gọi lần đầu tiên. Nếu bạn cần mở một cơ sở dữ liệu mới hoặc thực hiện một thao tác thiết lập khác chỉ cần diễn ra một lần cho tất cả phiên bản tiện ích, thì đây là nơi phù hợp để làm việc đó.
onDisabled(Context)
Lệnh này được gọi khi bản sao cuối cùng của tiện ích bị xoá khỏi máy chủ tiện ích. Đây là nơi bạn dọn dẹp mọi công việc đã làm trong
onEnabled(Context)
, chẳng hạn như xoá cơ sở dữ liệu tạm thời.onReceive(Context, Intent)
Lệnh này được gọi cho mọi thông báo truyền tin và trước mỗi lệnh gọi lại trước đó . Thông thường bạn không cần triển khai phương thức này, vì mặc định Phương thức triển khai
AppWidgetProvider
lọc tất cả các thông báo truyền tin tiện ích và gọi phương thức các phương thức trước đó khi thích hợp.
Bạn phải khai báo việc triển khai lớp AppWidgetProvider
ở dạng thông báo truyền tin
bằng cách sử dụng phần tử <receiver>
trong AndroidManifest
. Hãy xem bài viết Khai báo
trong tệp kê khai trên trang này để biết thêm thông tin.
Xử lý các sự kiện bằng lớp onUpdate()
Lệnh gọi lại AppWidgetProvider
quan trọng nhất là onUpdate()
vì
được gọi khi mỗi tiện ích được thêm vào máy chủ lưu trữ, trừ khi bạn sử dụng cấu hình
hoạt động không có cờ configuration_optional
. Nếu tiện ích của bạn chấp nhận bất kỳ
các sự kiện tương tác của người dùng, sau đó đăng ký trình xử lý sự kiện trong lệnh gọi lại này. Nếu
tiện ích của bạn không tạo tệp hoặc cơ sở dữ liệu tạm thời hoặc thực hiện công việc khác
cần dọn dẹp, thì onUpdate()
có thể là phương thức gọi lại duy nhất mà bạn
cần xác định.
Ví dụ: nếu bạn muốn một tiện ích có một nút khởi chạy một hoạt động khi
đã nhấn, bạn có thể sử dụng cách triển khai sau của AppWidgetProvider
:
Kotlin
class ExampleAppWidgetProvider : AppWidgetProvider() { override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // Perform this loop procedure for each widget that belongs to this // provider. appWidgetIds.forEach { appWidgetId -> // Create an Intent to launch ExampleActivity. val pendingIntent: PendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ Intent(context, ExampleActivity::class.java), /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // Get the layout for the widget and attach an onClick listener to // the button. val views: RemoteViews = RemoteViews( context.packageName, R.layout.appwidget_provider_layout ).apply { setOnClickPendingIntent(R.id.button, pendingIntent) } // Tell the AppWidgetManager to perform an update on the current // widget. appWidgetManager.updateAppWidget(appWidgetId, views) } } }
Java
public class ExampleAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Perform this loop procedure for each widget that belongs to this // provider. for (int i=0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; // Create an Intent to launch ExampleActivity Intent intent = new Intent(context, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ intent, /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // Get the layout for the widget and attach an onClick listener to // the button. RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); // Tell the AppWidgetManager to perform an update on the current app // widget. appWidgetManager.updateAppWidget(appWidgetId, views); } } }
AppWidgetProvider
này chỉ xác định phương thức onUpdate()
bằng cách sử dụng nó để
tạo một PendingIntent
để chạy
Activity
và đính kèm thẻ này vào
bằng cách sử dụng setOnClickPendingIntent(int,
PendingIntent)
. Nó có một vòng lặp lặp lại qua mỗi mục nhập
trong appWidgetIds
, là một mảng mã nhận dạng giúp nhận dạng từng tiện ích được tạo bởi
nhà cung cấp này. Nếu người dùng tạo nhiều phiên bản của tiện ích, thì
đều cập nhật đồng thời. Tuy nhiên, chỉ có một lịch biểu updatePeriodMillis
được quản lý cho mọi bản sao của tiện ích. Ví dụ: nếu lịch cập nhật
được xác định là hai giờ một lần và phiên bản thứ hai của tiện ích được thêm vào
một giờ sau quảng cáo đầu tiên, sau đó cả hai sẽ được cập nhật vào khoảng thời gian được xác định bằng
giai đoạn cập nhật đầu tiên và giai đoạn cập nhật thứ hai bị bỏ qua. Cả hai đều cập nhật mỗi 2
giờ, chứ không phải mỗi giờ.
Xem
ExampleAppWidgetProvider.java
lớp mẫu để biết thêm chi tiết.
Nhận ý định truyền tin của tiện ích
AppWidgetProvider
là một lớp tiện lợi. Nếu bạn muốn nhận tiện ích
thông báo truyền phát trực tiếp, bạn có thể triển khai BroadcastReceiver
của riêng mình hoặc ghi đè
thời gian
Lệnh gọi lại onReceive(Context,Intent)
. Ý định bạn cần quan tâm là
sau:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
Tạo bố cục tiện ích
Bạn phải xác định bố cục ban đầu cho tiện ích trong XML và lưu bố cục đó trong
thư mục res/layout/
của dự án. Tham khảo phần Thiết kế
để biết thông tin chi tiết.
Việc tạo bố cục tiện ích rất đơn giản nếu bạn quen dùng
bố cục. Tuy nhiên, hãy lưu ý rằng tiện ích
bố cục dựa trên RemoteViews
,
vốn không hỗ trợ mọi loại bố cục hoặc tiện ích khung hiển thị. Bạn không thể sử dụng tuỳ chỉnh
khung hiển thị hoặc lớp con của khung hiển thị được RemoteViews
hỗ trợ.
RemoteViews
cũng hỗ trợ ViewStub
,
đây là một View
vô hình, có kích thước bằng 0 mà bạn có thể sử dụng để tăng cường từng phần bố cục
trong thời gian chạy.
Hỗ trợ hành vi có trạng thái
Android 12 hỗ trợ thêm hành vi có trạng thái bằng cách sử dụng các tính năng sau thành phần hiện có:
Tiện ích này vẫn không có trạng thái. Ứng dụng của bạn phải lưu trữ tiểu bang và đăng ký các sự kiện thay đổi trạng thái.
Ví dụ về mã sau đây cho thấy cách triển khai các thành phần này.
Kotlin
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true) // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2) // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent) )
Java
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true); // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2); // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));
Cung cấp 2 bố cục: 1 thiết bị nhắm đến thiết bị chạy Android 12 hoặc
cao hơn trong res/layout-v31
và nhắm mục tiêu khác trước đó
Android 11 trở xuống trong thư mục res/layout
mặc định.
Triển khai các góc tròn
Android 12 ra mắt các tham số hệ thống sau đây để đặt giá trị bán kính bo tròn của tiện ích:
system_app_widget_background_radius
: bán kính góc của nền tiện ích, bán kính này không bao giờ lớn hơn 28 dp.system_app_widget_inner_radius
: bán kính góc của bất kỳ chế độ xem nào bên trong tiện ích. Đây chính xác là 8 dp nhỏ hơn bán kính nền để căn chỉnh hợp lý khi sử dụng 8 dp khoảng đệm.
Ví dụ sau đây cho thấy một tiện ích sử dụng
system_app_widget_background_radius
cho góc của tiện ích và
system_app_widget_inner_radius
cho các khung hiển thị bên trong tiện ích.
1 Góc của tiện ích.
2 Góc của thành phần hiển thị bên trong tiện ích.
Lưu ý quan trọng đối với góc tròn
- Trình chạy và nhà sản xuất thiết bị của bên thứ ba có thể ghi đè
Tham số
system_app_widget_background_radius
phải nhỏ hơn 28 dp. Tham sốsystem_app_widget_inner_radius
luôn nhỏ hơn 8 dp giá trị củasystem_app_widget_background_radius
. - Nếu tiện ích của bạn không sử dụng
@android:id/background
hoặc xác định nền cắt ngắn nội dung dựa trên bố cục — bằngandroid:clipToOutline
được đặt thànhtrue
– trình chạy tự động xác định nền và cắt tiện ích bằng một hình chữ nhật với góc bo tròn tối đa 16 dp. Xem phần Đảm bảo tiện ích của bạn tương thích với Android 12.
Để đảm bảo khả năng tương thích của tiện ích với các phiên bản Android trước, bạn nên xác định các thuộc tính tuỳ chỉnh và sử dụng một giao diện tuỳ chỉnh để ghi đè các thuộc tính đó Android 12, như minh hoạ trong các tệp XML mẫu sau:
/values/attrs.xml
<resources>
<attr name="backgroundRadius" format="dimension" />
</resources>
/values/styles.xml
<resources>
<style name="MyWidgetTheme">
<item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
</style>
</resources>
/values-31/styles.xml
<resources>
<style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
</style>
</resources>
/drawable/my_widget_background.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="?attr/backgroundRadius" />
...
</shape>
/layout/my_widget_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:background="@drawable/my_widget_background" />