วิดเจ็ตแอปคือมุมมองแอปขนาดเล็กที่คุณฝังในแอปอื่นๆ ได้ เช่น หน้าจอหลัก และรับการอัปเดตเป็นระยะๆ มุมมองเหล่านี้เรียกว่าวิดเจ็ตในอินเทอร์เฟซผู้ใช้ และคุณสามารถเผยแพร่มุมมองดังกล่าวได้โดยใช้ผู้ให้บริการวิดเจ็ตแอป (หรือผู้ให้บริการวิดเจ็ต) ส่วนประกอบของแอปที่ มีวิดเจ็ตอื่นๆ เรียกว่าโฮสต์วิดเจ็ตแอป (หรือโฮสต์วิดเจ็ต) รูปที่ 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
extends 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
การเรียกกลับที่สำคัญที่สุดคือ 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" />