วิดเจ็ตแอปคือมุมมองแอปขนาดย่อที่คุณฝังในแอปอื่นๆ ได้ เช่น หน้าจอหลัก และรับการอัปเดตเป็นระยะๆ มุมมองเหล่านี้เรียกว่าวิดเจ็ตในอินเทอร์เฟซผู้ใช้ และคุณสามารถเผยแพร่มุมมองดังกล่าวได้โดยใช้ผู้ให้บริการวิดเจ็ตแอป (หรือผู้ให้บริการวิดเจ็ต) ส่วนประกอบของแอปที่ มีวิดเจ็ตอื่นๆ เรียกว่าโฮสต์วิดเจ็ตแอป (หรือโฮสต์วิดเจ็ต) รูปที่ 1 แสดงตัวอย่างวิดเจ็ตเพลง

เอกสารนี้อธิบายวิธีเผยแพร่วิดเจ็ตโดยใช้ผู้ให้บริการวิดเจ็ต โปรดดูรายละเอียดเกี่ยวกับการสร้าง AppWidgetHost
ของคุณเองเพื่อโฮสต์วิดเจ็ตแอปที่หัวข้อสร้างโฮสต์วิดเจ็ต
ดูข้อมูลเกี่ยวกับวิธีออกแบบวิดเจ็ตได้ที่ภาพรวมวิดเจ็ตแอป
คอมโพเนนต์วิดเจ็ต
หากต้องการสร้างวิดเจ็ต คุณต้องมีคอมโพเนนต์พื้นฐานต่อไปนี้
- ออบเจ็กต์
AppWidgetProviderInfo
- อธิบายข้อมูลเมตาของวิดเจ็ต เช่น เลย์เอาต์ของวิดเจ็ต ความถี่ในการอัปเดต และคลาส
AppWidgetProvider
AppWidgetProviderInfo
กำหนดไว้ใน XML ตามที่อธิบายไว้ในเอกสารนี้ AppWidgetProvider
ชั้นเรียน- กำหนดวิธีการพื้นฐานที่ช่วยให้คุณเชื่อมต่อกับวิดเจ็ตโดยใช้โปรแกรมได้
โดยคุณจะได้รับการออกอากาศเมื่อมีการอัปเดต
เปิดใช้ ปิดใช้ หรือลบวิดเจ็ต คุณประกาศ
AppWidgetProvider
ใน ไฟล์ Manifest แล้วติดตั้งใช้งานตามที่ อธิบายไว้ในเอกสารนี้ - ดูเลย์เอาต์
- กำหนดเลย์เอาต์เริ่มต้นสำหรับวิดเจ็ต เลย์เอาต์กำหนดไว้ใน XML ตามที่อธิบายไว้ในเอกสารนี้
รูปที่ 2 แสดงให้เห็นว่าคอมโพเนนต์เหล่านี้เข้ากับโฟลว์การประมวลผลวิดเจ็ตแอปโดยรวมได้อย่างไร

หากวิดเจ็ตต้องมีการกำหนดค่าของผู้ใช้ ให้ใช้กิจกรรมการกำหนดค่าวิดเจ็ตแอป กิจกรรมนี้ช่วยให้ผู้ใช้แก้ไขการตั้งค่าวิดเจ็ตได้ เช่น เขตเวลาสำหรับวิดเจ็ตนาฬิกา
- ตั้งแต่ Android 12 (API ระดับ 31) เป็นต้นไป คุณสามารถระบุค่ากำหนด เริ่มต้นและอนุญาตให้ผู้ใช้กำหนดค่าวิดเจ็ตใหม่ได้ในภายหลัง ดูรายละเอียดเพิ่มเติมได้ที่ใช้การกำหนดค่าเริ่มต้นของวิดเจ็ตและเปิดใช้ให้ผู้ใช้กำหนดค่าวิดเจ็ตที่วางไว้ใหม่
- ใน Android 11 (API ระดับ 30) หรือต่ำกว่า ระบบจะเปิดใช้งานนี้ทุกครั้งที่ผู้ใช้เพิ่มวิดเจ็ตลงในหน้าจอหลัก
นอกจากนี้ เรายังแนะนำการปรับปรุงต่อไปนี้ด้วย ได้แก่ เลย์เอาต์วิดเจ็ตที่ยืดหยุ่น การปรับปรุงอื่นๆ วิดเจ็ตขั้นสูง วิดเจ็ตคอลเล็กชัน และการสร้างวิดเจ็ต โฮสต์
ประกาศ XML ของ AppWidgetProviderInfo
ออบเจ็กต์ AppWidgetProviderInfo
จะกำหนดคุณสมบัติที่จำเป็นของวิดเจ็ต
กำหนดออบเจ็กต์ AppWidgetProviderInfo
ในไฟล์ทรัพยากร XML โดยใช้องค์ประกอบ
<appwidget-provider>
เดียว แล้วบันทึกไว้ในโฟลเดอร์ res/xml/
ของโปรเจ็กต์
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการดำเนินการนี้
<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>
แอตทริบิวต์การปรับขนาดวิดเจ็ต
หน้าจอหลักเริ่มต้นจะวางวิดเจ็ตในหน้าต่างตามตารางกริดของเซลล์ ที่มีความสูงและความกว้างที่กำหนด หน้าจอหลักส่วนใหญ่จะอนุญาตให้วิดเจ็ตมีขนาดเป็นจำนวนเต็มเท่าของเซลล์กริดเท่านั้น เช่น 2 เซลล์ในแนวนอนและ 3 เซลล์ในแนวตั้ง
แอตทริบิวต์การกำหนดขนาดวิดเจ็ตช่วยให้คุณระบุขนาดเริ่มต้นสำหรับวิดเจ็ตและ ระบุขอบเขตล่างและบนของขนาดวิดเจ็ตได้ ในบริบทนี้ ขนาดเริ่มต้นของวิดเจ็ตคือขนาดที่วิดเจ็ตใช้เมื่อ เพิ่มลงในหน้าจอหลักเป็นครั้งแรก
ตารางต่อไปนี้จะอธิบายแอตทริบิวต์ <appwidget-provider>
ที่เกี่ยวข้อง
กับการปรับขนาดวิดเจ็ต
แอตทริบิวต์และคำอธิบาย | |
---|---|
targetCellWidth และ
targetCellHeight (Android 12)
minWidth และ minHeight |
targetCellWidth และ
targetCellHeight รวมถึง minWidth และ
minHeight เพื่อให้แอปของคุณกลับไปใช้
minWidth และ minHeight ได้หากอุปกรณ์ของผู้ใช้
ไม่รองรับ targetCellWidth และ
targetCellHeight หากรองรับ แอตทริบิวต์
targetCellWidth และ targetCellHeight
จะมีความสำคัญเหนือกว่าแอตทริบิวต์ minWidth และ minHeight
|
minResizeWidth และ
minResizeHeight |
ระบุขนาดขั้นต่ำที่แน่นอนของวิดเจ็ต ค่าเหล่านี้ระบุ
ขนาดที่วิดเจ็ตอ่านไม่ออกหรือใช้ไม่ได้ การใช้
แอตทริบิวต์เหล่านี้ช่วยให้ผู้ใช้ปรับขนาดวิดเจ็ตให้มีขนาดเล็กกว่า
ขนาดวิดเจ็ตเริ่มต้นได้ ระบบจะละเว้นแอตทริบิวต์ minResizeWidth หากมีค่ามากกว่า minWidth หรือหากไม่ได้เปิดใช้การปรับขนาดแนวนอน ดูresizeMode ในทำนองเดียวกัน ระบบจะละเว้นแอตทริบิวต์ minResizeHeight หากมีค่ามากกว่า minHeight หรือหากไม่ได้เปิดใช้การปรับขนาดแนวตั้ง |
maxResizeWidth และ
maxResizeHeight |
ระบุขนาดสูงสุดที่แนะนำของวิดเจ็ต หากค่าไม่ใช่
ผลคูณของขนาดเซลล์กริด ระบบจะปัดเศษขึ้นเป็นขนาดเซลล์ที่ใกล้เคียงที่สุด
ระบบจะละเว้นแอตทริบิวต์ maxResizeWidth หากมีขนาดเล็กกว่า minWidth หรือหากไม่ได้เปิดใช้การปรับขนาดแนวนอน ดู resizeMode ในทำนองเดียวกัน
ระบบจะละเว้นแอตทริบิวต์ maxResizeHeight หากมีค่ามากกว่า
minHeight หรือหากไม่ได้เปิดใช้การปรับขนาดแนวตั้ง
เปิดตัวใน Android 12 |
resizeMode |
ระบุกฎที่ใช้ในการปรับขนาดวิดเจ็ต คุณใช้แอตทริบิวต์นี้
เพื่อทำให้วิดเจ็ตหน้าจอหลักปรับขนาดได้ในแนวนอน แนวตั้ง
หรือทั้ง 2 แกน ผู้ใช้แตะวิดเจ็ตค้างไว้เพื่อแสดงแฮนเดิลปรับขนาด
จากนั้นลากแฮนเดิลแนวนอนหรือแนวตั้งเพื่อเปลี่ยนขนาดใน
ตารางกริดของเลย์เอาต์ ค่าสำหรับแอตทริบิวต์ resizeMode ได้แก่
horizontal , vertical และ none หากต้องการ
ประกาศวิดเจ็ตว่าปรับขนาดได้ทั้งแนวนอนและแนวตั้ง ให้ใช้
horizontal|vertical |
ตัวอย่าง
โปรดดูข้อมูลจำเพาะต่อไปนี้เพื่อดูว่าแอตทริบิวต์ในตารางก่อนหน้าส่งผลต่อการปรับขนาดวิดเจ็ตอย่างไร
- เซลล์ตารางกริดมีความกว้าง 30 dp และสูง 50 dp
- เราได้ระบุข้อกำหนดแอตทริบิวต์ต่อไปนี้
<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" />
ตั้งแต่ Android 12 เป็นต้นไป
ใช้แอตทริบิวต์ targetCellWidth
และ targetCellHeight
เป็นขนาดเริ่มต้นของวิดเจ็ต
วิดเจ็ตมีขนาด 2x2 โดยค่าเริ่มต้น คุณปรับขนาดวิดเจ็ตให้เล็กลงได้ถึง 2x1 หรือใหญ่ขึ้นได้ถึง 4x3
Android 11 และต่ำกว่า
ใช้แอตทริบิวต์ minWidth
และ minHeight
เพื่อคำนวณขนาดเริ่มต้นของ
วิดเจ็ต
ความกว้างเริ่มต้น = Math.ceil(80 / 30)
= 3
ความสูงเริ่มต้น = Math.ceil(80 / 50)
= 2
ขนาดเริ่มต้นของวิดเจ็ตคือ 3x2 คุณปรับขนาดวิดเจ็ตให้เล็กลงได้ถึง 2x1 หรือ ขยายให้เต็มหน้าจอได้
แอตทริบิวต์เพิ่มเติมของวิดเจ็ต
ตารางต่อไปนี้อธิบายแอตทริบิวต์ <appwidget-provider>
ที่เกี่ยวข้อง
กับคุณภาพอื่นๆ นอกเหนือจากการปรับขนาดวิดเจ็ต
แอตทริบิวต์และคำอธิบาย | |
---|---|
updatePeriodMillis |
กำหนดความถี่ที่เฟรมเวิร์กวิดเจ็ตขออัปเดตจาก
AppWidgetProvider โดยการเรียกใช้เมธอดเรียกกลับ onUpdate()
การอัปเดตจริงอาจไม่เกิดขึ้นตรงเวลาตามค่านี้เสมอไป และเราขอแนะนำให้อัปเดตให้น้อยที่สุดเท่าที่จะเป็นไปได้ โดยไม่เกิน 1 ครั้งต่อชั่วโมง เพื่อประหยัดแบตเตอรี่
ดูรายการข้อควรพิจารณาทั้งหมดในการเลือกช่วงเวลาอัปเดตที่เหมาะสมได้ที่
การเพิ่มประสิทธิภาพสำหรับการอัปเดตเนื้อหาวิดเจ็ต |
initialLayout |
ชี้ไปยังทรัพยากรเลย์เอาต์ที่กำหนดเลย์เอาต์ของวิดเจ็ต |
configure |
กำหนดกิจกรรมที่จะเปิดขึ้นเมื่อผู้ใช้เพิ่มวิดเจ็ต เพื่อให้ผู้ใช้กำหนดค่าพร็อพเพอร์ตี้ของวิดเจ็ตได้ ดู อนุญาตให้ผู้ใช้กำหนดค่าวิดเจ็ต ตั้งแต่ Android 12 เป็นต้นไป แอปจะข้ามการกำหนดค่าเริ่มต้นได้ ดูรายละเอียดได้ที่ใช้การกำหนดค่าเริ่มต้นของวิดเจ็ต |
description |
ระบุคำอธิบายสำหรับเครื่องมือเลือกวิดเจ็ตที่จะแสดงสำหรับวิดเจ็ต ของคุณ เปิดตัวใน Android 12 |
previewLayout (Android 12)
และ previewImage (Android 11 และต่ำกว่า) |
previewImage
และ previewLayout เพื่อให้แอปสามารถกลับไปใช้ previewImage ได้
หากอุปกรณ์ของผู้ใช้ไม่รองรับ previewLayout
โปรดดูรายละเอียดเพิ่มเติมที่
ความเข้ากันได้แบบย้อนหลังกับ
ตัวอย่างวิดเจ็ตที่ปรับขนาดได้
|
autoAdvanceViewId |
ระบุรหัสมุมมองของมุมมองย่อยของวิดเจ็ตที่โฮสต์ของวิดเจ็ตเลื่อนไปข้างหน้าโดยอัตโนมัติ |
widgetCategory |
ประกาศว่าวิดเจ็ตแสดงในหน้าจอหลัก (home_screen ), หน้าจอล็อก (keyguard ) หรือทั้ง 2 หน้าจอได้หรือไม่
สำหรับ Android 5.0 ขึ้นไป จะใช้ได้เฉพาะ home_screen
|
widgetFeatures |
ประกาศฟีเจอร์ที่วิดเจ็ตนี้รองรับ เช่น หากต้องการให้
วิดเจ็ตใช้การกำหนดค่าเริ่มต้นเมื่อผู้ใช้เพิ่มวิดเจ็ต ให้ระบุทั้ง
configuration_optional
และ
reconfigurable
ซึ่งจะข้ามการเปิดใช้งานการกำหนดค่าหลังจากที่ผู้ใช้
เพิ่มวิดเจ็ต ผู้ใช้จะยังคง
กำหนดค่าเครื่องมือใหม่
ได้ในภายหลัง |
ใช้คลาส AppWidgetProvider เพื่อจัดการการออกอากาศวิดเจ็ต
คลาส AppWidgetProvider
จะจัดการการออกอากาศวิดเจ็ตและอัปเดตวิดเจ็ต
เพื่อตอบสนองต่อเหตุการณ์วงจรของวิดเจ็ต ส่วนต่อไปนี้อธิบายวิธีประกาศ AppWidgetProvider
ในไฟล์ Manifest แล้วนำไปใช้
ประกาศวิดเจ็ตในไฟล์ Manifest
ก่อนอื่น ให้ประกาศคลาส AppWidgetProvider
ในไฟล์ AndroidManifest.xml
ของแอป ดังที่แสดงในตัวอย่างต่อไปนี้
<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>
องค์ประกอบ <receiver>
ต้องมีแอตทริบิวต์ android:name
ซึ่งระบุ AppWidgetProvider
ที่วิดเจ็ตใช้ ห้ามส่งออกคอมโพเนนต์
เว้นแต่จะต้องมีกระบวนการแยกต่างหากเพื่อออกอากาศไปยัง AppWidgetProvider
ซึ่งโดยปกติแล้ว
จะไม่ใช่กรณีนี้
องค์ประกอบ <intent-filter>
ต้องมีองค์ประกอบ <action>
ที่มีแอตทริบิวต์ android:name
แอตทริบิวต์นี้ระบุว่า AppWidgetProvider
ยอมรับACTION_APPWIDGET_UPDATE
การออกอากาศ นี่คือการออกอากาศเพียงรายการเดียวที่คุณต้องประกาศอย่างชัดเจน โดย
AppWidgetManager
จะส่งการออกอากาศวิดเจ็ตอื่นๆ ทั้งหมดไปยัง AppWidgetProvider
โดยอัตโนมัติ
ตามความจำเป็น
องค์ประกอบ <meta-data>
จะระบุAppWidgetProviderInfo
ทรัพยากรและต้องมีแอตทริบิวต์ต่อไปนี้
android:name
: ระบุชื่อข้อมูลเมตา ใช้android.appwidget.provider
เพื่อระบุข้อมูลเป็นตัวอธิบายAppWidgetProviderInfo
android:resource
: ระบุตำแหน่งของทรัพยากรAppWidgetProviderInfo
ใช้คลาส AppWidgetProvider
คลาส AppWidgetProvider
จะขยาย
BroadcastReceiver
เป็นคลาสอำนวยความสะดวกเพื่อจัดการการออกอากาศวิดเจ็ต โดยจะรับเฉพาะการออกอากาศเหตุการณ์ที่เกี่ยวข้องกับวิดเจ็ต เช่น เมื่อมีการอัปเดต
ลบ เปิดใช้ และปิดใช้วิดเจ็ต เมื่อเกิดเหตุการณ์การออกอากาศเหล่านี้ ระบบจะเรียกใช้AppWidgetProvider
วิธีการต่อไปนี้
onUpdate()
- ระบบจะเรียกใช้ฟังก์ชันนี้เพื่ออัปเดตวิดเจ็ตตามช่วงเวลาที่กำหนดโดยแอตทริบิวต์
updatePeriodMillis
ในAppWidgetProviderInfo
ดูข้อมูลเพิ่มเติมได้ที่ตาราง ที่อธิบายแอตทริบิวต์วิดเจ็ตเพิ่มเติมในหน้านี้ - เมธอดนี้จะเรียกใช้เมื่อผู้ใช้เพิ่มวิดเจ็ตด้วย จึงทำการตั้งค่าที่จำเป็น เช่น การกำหนดตัวแฮนเดิลเหตุการณ์สำหรับออบเจ็กต์
View
หรือการเริ่มงานเพื่อโหลดข้อมูลที่จะแสดงในวิดเจ็ต อย่างไรก็ตาม หากคุณประกาศกิจกรรมการกำหนดค่าโดยไม่มี แฟล็กconfiguration_optional
ระบบจะไม่เรียกใช้วิธีนี้เมื่อผู้ใช้ เพิ่มวิดเจ็ต แต่จะเรียกใช้สำหรับการอัปเดตในภายหลัง กิจกรรมการกำหนดค่ามี หน้าที่รับผิดชอบในการอัปเดตครั้งแรกเมื่อ การกำหนดค่าเสร็จสมบูรณ์ โปรดดูข้อมูลเพิ่มเติมที่หัวข้อเปิดใช้ให้ผู้ใช้กำหนดค่าวิดเจ็ตแอป - การเรียกกลับที่สำคัญที่สุดคือ
onUpdate()
ดูข้อมูลเพิ่มเติมได้ที่จัดการเหตุการณ์ด้วยคลาสonUpdate()
ในหน้านี้ onAppWidgetOptionsChanged()
เรียกใช้เมื่อวางวิดเจ็ตเป็นครั้งแรกและทุกครั้งที่ มีการปรับขนาดวิดเจ็ต ใช้การเรียกกลับนี้เพื่อแสดงหรือซ่อนเนื้อหาตามช่วงขนาดของวิดเจ็ต รับช่วงขนาด และตั้งแต่ Android 12 เป็นต้นไป รายการขนาดที่เป็นไปได้ที่อินสแตนซ์วิดเจ็ตใช้ได้โดยการเรียก
getAppWidgetOptions()
ซึ่งจะแสดงผลBundle
ที่มีข้อมูลต่อไปนี้OPTION_APPWIDGET_MIN_WIDTH
: มีขอบเขตล่างของความกว้างในหน่วย dp ของอินสแตนซ์วิดเจ็ตOPTION_APPWIDGET_MIN_HEIGHT
: มีขอบเขตล่างของความสูงในหน่วย dp ของอินสแตนซ์วิดเจ็ตOPTION_APPWIDGET_MAX_WIDTH
: มีขอบเขตบนของความกว้างในหน่วย dp ของอินสแตนซ์วิดเจ็ตOPTION_APPWIDGET_MAX_HEIGHT
: มีขอบเขตบนของความสูงในหน่วย dp ของอินสแตนซ์วิดเจ็ตOPTION_APPWIDGET_SIZES
: มีรายการขนาดที่เป็นไปได้ (List<SizeF>
) ในหน่วย dp ที่อินสแตนซ์วิดเจ็ต ใช้ได้ เปิดตัวใน Android 12
onDeleted(Context, int[])
ระบบจะเรียกใช้ฟังก์ชันนี้ทุกครั้งที่ลบวิดเจ็ตออกจากโฮสต์วิดเจ็ต
onEnabled(Context)
ระบบจะเรียกใช้ฟังก์ชันนี้เมื่อสร้างอินสแตนซ์ของวิดเจ็ตเป็นครั้งแรก เช่น หากผู้ใช้เพิ่มวิดเจ็ตของคุณ 2 อินสแตนซ์ ระบบจะเรียกใช้ฟังก์ชันนี้เฉพาะครั้งแรกเท่านั้น หากคุณต้องการเปิดฐานข้อมูลใหม่หรือทำการตั้งค่าอื่นที่ จำเป็นต้องทำเพียงครั้งเดียวสำหรับอินสแตนซ์วิดเจ็ตทั้งหมด นี่คือตำแหน่งที่เหมาะสม ในการดำเนินการ
onDisabled(Context)
ระบบจะเรียกใช้ฟังก์ชันนี้เมื่อลบอินสแตนซ์สุดท้ายของวิดเจ็ตออกจาก โฮสต์วิดเจ็ต ส่วนนี้คือที่ที่คุณจะล้างงานที่ทำใน
onEnabled(Context)
เช่น การลบฐานข้อมูลชั่วคราวonReceive(Context, Intent)
ระบบจะเรียกใช้เมธอดนี้สำหรับการออกอากาศทุกครั้งและก่อนเมธอดเรียกกลับก่อนหน้าแต่ละรายการ โดยปกติแล้วคุณไม่จำเป็นต้องใช้เมธอดนี้ เนื่องจาก
AppWidgetProvider
การใช้งานเริ่มต้นจะกรองการออกอากาศของวิดเจ็ตทั้งหมดและเรียกใช้เมธอดก่อนหน้าตามความเหมาะสม
คุณต้องประกาศการใช้งานคลาส AppWidgetProvider
เป็น Broadcast
Receiver โดยใช้องค์ประกอบ <receiver>
ใน AndroidManifest
ดูข้อมูลเพิ่มเติมได้ที่ประกาศวิดเจ็ตในไฟล์ Manifest ในหน้านี้
จัดการเหตุการณ์ด้วยคลาส onUpdate()
AppWidgetProvider
Callback ที่สำคัญที่สุดคือ onUpdate()
เนื่องจากจะมีการเรียกใช้เมื่อเพิ่มวิดเจ็ตแต่ละรายการลงในโฮสต์ เว้นแต่คุณจะใช้กิจกรรมการกำหนดค่าที่ไม่มีแฟล็ก configuration_optional
หากวิดเจ็ตยอมรับเหตุการณ์การโต้ตอบของผู้ใช้ ให้ลงทะเบียนตัวแฮนเดิลเหตุการณ์ใน Callback นี้ หากวิดเจ็ตไม่ได้สร้างไฟล์หรือฐานข้อมูลชั่วคราว หรือทำงานอื่นๆ
ที่ต้องมีการล้างข้อมูล onUpdate()
อาจเป็นเมธอดการเรียกกลับเพียงเมธอดเดียวที่คุณ
ต้องกำหนด
ตัวอย่างเช่น หากต้องการวิดเจ็ตที่มีปุ่มซึ่งเปิดใช้กิจกรรมเมื่อมีการแตะ คุณสามารถใช้การติดตั้งใช้งาน 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
นี้จะกำหนดเฉพาะเมธอด onUpdate()
โดยใช้เมธอดนี้เพื่อ
สร้าง PendingIntent
ที่เปิด
Activity
และแนบไปกับปุ่มของวิดเจ็ต
โดยใช้ setOnClickPendingIntent(int,
PendingIntent)
โดยมีลูปที่วนซ้ำในแต่ละรายการ
ใน appWidgetIds
ซึ่งเป็นอาร์เรย์ของรหัสที่ระบุวิดเจ็ตแต่ละรายการที่สร้างโดย
ผู้ให้บริการรายนี้ หากผู้ใช้สร้างวิดเจ็ตมากกว่า 1 รายการ วิดเจ็ตทั้งหมดจะอัปเดตพร้อมกัน
อย่างไรก็ตาม ระบบจะจัดการupdatePeriodMillis
กำหนดเวลา
เพียงรายการเดียวสำหรับวิดเจ็ตทุกอินสแตนซ์ เช่น หากกำหนดตารางเวลาการอัปเดต
ให้ทุก 2 ชั่วโมง และเพิ่มวิดเจ็ตอินสแตนซ์ที่ 2
หลังจากอินสแตนซ์แรก 1 ชั่วโมง ทั้ง 2 อินสแตนซ์จะได้รับการอัปเดตตามระยะเวลาที่กำหนดโดย
อินสแตนซ์แรก และระบบจะไม่สนใจระยะเวลาการอัปเดตที่ 2 ทั้ง 2 อย่างจะอัปเดตทุก 2 ชั่วโมง ไม่ใช่ทุกชั่วโมง
ดูรายละเอียดเพิ่มเติมได้ที่คลาสตัวอย่าง
ExampleAppWidgetProvider.java
รับ Intent การออกอากาศของวิดเจ็ต
AppWidgetProvider
เป็นคลาสช่วยอำนวยความสะดวก หากต้องการรับการออกอากาศวิดเจ็ตโดยตรง คุณสามารถใช้ BroadcastReceiver
ของคุณเองหรือลบล้าง
การเรียกกลับ
onReceive(Context,Intent)
Intent ที่คุณต้องสนใจมีดังนี้
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
สร้างเลย์เอาต์วิดเจ็ต
คุณต้องกำหนดเลย์เอาต์เริ่มต้นสำหรับวิดเจ็ตใน XML และบันทึกไว้ในไดเรกทอรี res/layout/
ของโปรเจ็กต์ ดูรายละเอียดได้ในหลักเกณฑ์
การออกแบบ
การสร้างเลย์เอาต์วิดเจ็ตนั้นตรงไปตรงมาหากคุณคุ้นเคยกับเลย์เอาต์ อย่างไรก็ตาม โปรดทราบว่าเลย์เอาต์วิดเจ็ต
อิงตาม RemoteViews
ซึ่งไม่รองรับเลย์เอาต์หรือวิดเจ็ตมุมมองทุกประเภท คุณไม่สามารถใช้มุมมองที่กำหนดเองหรือคลาสย่อยของมุมมองที่ RemoteViews
รองรับ
RemoteViews
ยังรองรับ ViewStub
ซึ่งเป็น View
ที่มองไม่เห็นและมีขนาดเป็น 0 ซึ่งคุณใช้เพื่อขยายเลย์เอาต์
ทรัพยากรแบบเลซีโหลดได้ในรันไทม์
รองรับลักษณะการทำงานแบบมีสถานะ
Android 12 เพิ่มการรองรับลักษณะการทำงานแบบมีสถานะโดยใช้คอมโพเนนต์ที่มีอยู่ต่อไปนี้
วิดเจ็ตยังคงไม่มีสถานะ แอปต้องจัดเก็บสถานะและลงทะเบียนเพื่อรับ เหตุการณ์การเปลี่ยนแปลงสถานะ

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีติดตั้งใช้งานคอมโพเนนต์เหล่านี้
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));
ระบุเลย์เอาต์ 2 รายการ ได้แก่ รายการหนึ่งที่กำหนดเป้าหมายเป็นอุปกรณ์ที่ใช้ Android 12 ขึ้นไปใน res/layout-v31
และอีกรายการหนึ่งที่กำหนดเป้าหมายเป็น Android 11 หรือต่ำกว่าในโฟลเดอร์ res/layout
เริ่มต้น
ใช้มุมโค้งมน
Android 12 เปิดตัวพารามิเตอร์ระบบต่อไปนี้เพื่อตั้งค่า รัศมีของมุมโค้งของวิดเจ็ต
system_app_widget_background_radius
: รัศมีมุมของพื้นหลังวิดเจ็ต ซึ่งไม่เกิน 28 dpรัศมีด้านใน ซึ่งคำนวณได้จากรัศมีด้านนอกและการเว้นวรรค ดูข้อมูลโค้ดต่อไปนี้
/** * Applies corner radius for views that are visually positioned [widgetPadding]dp inside of the * widget background. */ @Composable fun GlanceModifier.appWidgetInnerCornerRadius(widgetPadding: Dp): GlanceModifier { if (Build.VERSION.SDK_INT < 31) { return this } val resources = LocalContext.current.resources // get dimension in float (without rounding). val px = resources.getDimension(android.R.dimen.system_app_widget_background_radius) val widgetBackgroundRadiusDpValue = px / resources.displayMetrics.density if (widgetBackgroundRadiusDpValue < widgetPadding.value) { return this } return this.cornerRadius(Dp(widgetBackgroundRadiusDpValue - widgetPadding.value)) }
หากต้องการคำนวณรัศมีที่เหมาะสมสำหรับเนื้อหาด้านในของวิดเจ็ต ให้ใช้สูตรต่อไปนี้ systemRadiusValue - widgetPadding
วิดเจ็ตที่ตัดเนื้อหาให้เป็นรูปร่างที่ไม่ใช่สี่เหลี่ยมผืนผ้าควรใช้
@android:id/background
เป็นรหัสมุมมองของมุมมองพื้นหลังที่มี
android:clipToOutline
ตั้งค่าเป็น true
ข้อควรพิจารณาที่สำคัญสำหรับมุมโค้ง
- ตัวเรียกใช้งานของบุคคลที่สามและผู้ผลิตอุปกรณ์สามารถลบล้างพารามิเตอร์
system_app_widget_background_radius
ให้มีขนาดเล็กกว่า 28 dp ได้ หากวิดเจ็ตไม่ได้ใช้
@android:id/background
หรือกำหนดพื้นหลัง ที่ตัดเนื้อหาตามโครงร่างโดยตั้งค่าandroid:clipToOutline
เป็นtrue
ตัวเรียกใช้จะระบุพื้นหลังโดยอัตโนมัติและตัด วิดเจ็ตโดยใช้สี่เหลี่ยมผืนผ้าที่มีมุมโค้งซึ่งตั้งค่าเป็นรัศมีของระบบรูปร่างที่ไม่ใช่สี่เหลี่ยมผืนผ้าต้องอยู่ในคอนเทนเนอร์การปรับขนาดสี่เหลี่ยมผืนผ้าโค้งมน เพื่อไม่ให้ถูกตัด
ตั้งแต่ Android 16 เป็นต้นไป ค่าระบบ AOSP สำหรับ
system_app_widget_background_radius
คือ24dp
โปรแกรมเรียกใช้และผู้ผลิตอุปกรณ์อาจตัดวิดเจ็ตให้พอดีกับsystem_app_widget_background_radius
เนื้อหาด้านในของวิดเจ็ตต้องมีระยะขอบเพียงพอที่จะรองรับ
system_app_widget_background_radius
ค่ารัศมีสูงสุด28dp
เพื่อหลีกเลี่ยงไม่ให้มุมโค้งตัดเนื้อหา
หากต้องการให้วิดเจ็ตใช้งานร่วมกับ Android เวอร์ชันก่อนหน้าได้ เราขอแนะนำให้ กำหนดแอตทริบิวต์ที่กำหนดเองและใช้ธีมที่กำหนดเองเพื่อลบล้างแอตทริบิวต์เหล่านั้นสำหรับ Android 12 ดังที่แสดงในไฟล์ XML ตัวอย่างต่อไปนี้
/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" />