สร้างวิดเจ็ตแอปด้วย "ข้อมูลโดยย่อ"

ส่วนต่อไปนี้จะอธิบายวิธีสร้างวิดเจ็ตแอปพื้นฐานด้วย Glance

ประกาศ AppWidget ในไฟล์ Manifest

หลังจากทำตามขั้นตอนการตั้งค่าเสร็จแล้ว ให้ประกาศ AppWidget และข้อมูลเมตาในแอป

  1. ขยายตัวรับ AppWidget จาก GlanceAppWidgetReceiver:

    class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
        override val glanceAppWidget: GlanceAppWidget = TODO("Create GlanceAppWidget")
    }

  2. ลงทะเบียนผู้ให้บริการวิดเจ็ตแอปในไฟล์ AndroidManifest.xml และไฟล์ข้อมูลเมตาที่เกี่ยวข้อง ดังนี้

        <receiver android:name=".glance.MyReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/my_app_widget_info" />
    </receiver>
    

เพิ่มข้อมูลเมตา AppWidgetProviderInfo

จากนั้นทำตามคำแนะนำสร้างวิดเจ็ตเพื่อสร้างและกำหนดข้อมูลวิดเจ็ตแอปในไฟล์ @xml/my_app_widget_info

ความแตกต่างเพียงอย่างเดียวสำหรับ Glance คือไม่มี initialLayout XML แต่คุณต้องกำหนดไว้ คุณสามารถใช้เลย์เอาต์การโหลดที่กำหนดไว้ล่วงหน้าซึ่งมีอยู่ในไลบรารีต่อไปนี้

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/glance_default_loading_layout">
</appwidget-provider>

ประกาศ XML ของ AppWidgetProviderInfo

ออบเจ็กต์ AppWidgetProviderInfo จะกำหนดคุณสมบัติที่สำคัญของวิดเจ็ต กำหนด AppWidgetProviderInfo ในไฟล์ทรัพยากรข้อมูลเมตา XML (res/xml/my_app_widget_info.xml) ภายในองค์ประกอบ <appwidget-provider> ดังนี้

<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/glance_default_loading_layout"
    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
  • ตั้งแต่ Android 12 เป็นต้นไป แอตทริบิวต์ targetCellWidth และ targetCellHeight จะระบุขนาดเริ่มต้นของวิดเจ็ตในแง่ของเซลล์ตารางกริด ระบบจะไม่สนใจแอตทริบิวต์เหล่านี้ใน Android 11 และต่ำกว่า และอาจไม่สนใจหากหน้าจอหลักไม่รองรับเลย์เอาต์แบบตารางกริด
  • แอตทริบิวต์ minWidth และ minHeight จะระบุขนาดเริ่มต้นของวิดเจ็ตเป็น dp หากค่าความกว้างหรือความสูงขั้นต่ำของวิดเจ็ตไม่ตรงกับขนาดของเซลล์ ระบบจะปัดเศษค่าดังกล่าวขึ้นเป็นขนาดเซลล์ที่ใกล้เคียงที่สุด
เราขอแนะนำให้ระบุแอตทริบิวต์ทั้ง 2 ชุด ได้แก่ 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 กำหนดความถี่ที่เฟรมเวิร์กวิดเจ็ตจะขออัปเดตจาก GlanceAppWidgetReceiver โดยเรียกใช้เมธอด Callback onUpdate() เราขอแนะนำให้อัปเดตให้น้อยที่สุดเท่าที่จะเป็นไปได้ โดยไม่เกิน 1 ครั้งต่อชั่วโมง เพื่อประหยัดแบตเตอรี่ ดูรายละเอียดได้ที่ส่วนกรณีที่ควรอัปเดตวิดเจ็ตในการจัดการสถานะ Glance
initialLayout ชี้ไปยังทรัพยากรเลย์เอาต์ที่กำหนดเลย์เอาต์การโหลดของวิดเจ็ตก่อนที่องค์ประกอบ UI ของ Glance จะแสดงผล คุณสามารถใช้เลย์เอาต์การโหลดที่กำหนดไว้ล่วงหน้าซึ่งมีอยู่ในไลบรารี @layout/glance_default_loading_layout
configure กำหนดกิจกรรมการกำหนดค่าที่จะเปิดขึ้นเมื่อผู้ใช้เพิ่มวิดเจ็ต ดูคำแนะนำในหัวข้อเปิดใช้ผู้ใช้เพื่อกำหนดค่าวิดเจ็ตแอป
description ระบุคำอธิบายสำหรับเครื่องมือเลือกวิดเจ็ตที่จะแสดงสำหรับวิดเจ็ตของคุณ เปิดตัวใน Android 12
previewLayout (Android 12) และ previewImage (Android 11 และต่ำกว่า)
  • ตั้งแต่ Android 12 เป็นต้นไป แอตทริบิวต์ previewLayout จะระบุตัวอย่างที่ปรับขนาดได้ ซึ่งคุณระบุเป็นเลย์เอาต์ XML ที่ตั้งค่าเป็นขนาดเริ่มต้นของวิดเจ็ต โดยหลักการแล้ว ไฟล์นี้จะชี้ไปยังการแมป XML แบบคงที่ซึ่งตรงกับเลย์เอาต์การออกแบบของคุณ
  • ใน Android 11 หรือต่ำกว่า แอตทริบิวต์ previewImage จะระบุภาพหน้าจอที่ถอนออกได้ของรูปภาพนิ่งซึ่งแสดงลักษณะของวิดเจ็ต โดยจะปรากฏในเครื่องมือเลือกวิดเจ็ต
เราขอแนะนำให้ระบุทั้ง 2 อย่างเพื่อให้แอปของคุณทำงานได้อย่างราบรื่นบนแพลตฟอร์มที่เก่ากว่า สำหรับแพลตฟอร์มที่ใหม่กว่า (Android 15 ขึ้นไป) คุณสามารถกำหนดตัวอย่างที่สร้างขึ้นแบบเรียลไทม์ใน Kotlin โดยใช้ `GlanceAppWidget.providePreview` ดูคำแนะนำเกี่ยวกับตัวอย่างที่สร้างขึ้น
autoAdvanceViewId ระบุรหัสการแสดงผลของมุมมองย่อยของวิดเจ็ตที่โฮสต์ของวิดเจ็ตเลื่อนโดยอัตโนมัติ
widgetCategory ประกาศว่าวิดเจ็ตของคุณจะแสดงในหน้าจอหลัก (home_screen) หน้าจอล็อก (keyguard) หรือทั้ง 2 หน้าจอได้หรือไม่ สำหรับ Android 5.0 ขึ้นไป จะใช้ได้เฉพาะ home_screen เท่านั้น
widgetFeatures ประกาศฟีเจอร์ที่วิดเจ็ตรองรับ เช่น หากการกำหนดค่าวิดเจ็ตเป็นแบบไม่บังคับ ให้ระบุทั้ง configuration_optional และ reconfigurable

จำกัดความ GlanceAppWidget

  1. สร้างคลาสใหม่ที่ขยายจาก GlanceAppWidget และลบล้างเมธอด provideGlance วิธีนี้ช่วยให้คุณโหลดข้อมูลที่จำเป็นต่อการแสดงผลวิดเจ็ตได้

    class MyAppWidget : GlanceAppWidget() {
    
        override suspend fun provideGlance(context: Context, id: GlanceId) {
    
            // In this method, load data needed to render the AppWidget.
            // Use `withContext` to switch to another thread for long running
            // operations.
    
            provideContent {
                // create your AppWidget here
                Text("Hello World")
            }
        }
    }

  2. สร้างอินสแตนซ์ใน glanceAppWidget บน GlanceAppWidgetReceiver ดังนี้

    class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
    
        // Let MyAppWidgetReceiver know which GlanceAppWidget to use
        override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
    }

ตอนนี้คุณได้กำหนดค่า AppWidget โดยใช้ Glance แล้ว

จัดการหน่วยความจำรูปภาพของวิดเจ็ตในที่เก็บข้อมูลขนาดต่างๆ

เมื่อวิดเจ็ตแสดงบิตแมปหรือ URI รูปภาพ content:// ให้รักษาหน่วยความจำรูปภาพ RemoteViews ที่เรียงลำดับทั้งหมดให้อยู่ภายในขีดจำกัดของระบบ (6 * width * height ไบต์ ซึ่งบังคับใช้ด้วย IllegalArgumentException ใน Android 17 ขึ้นไป) โดยทำดังนี้

  • ถอดรหัสบิตแมปที่แชร์ก่อน provideContent: หากวิดเจ็ตใช้ SizeMode.Responsive หรือ SizeMode.Exact Glance จะเรียกใช้ Lambda provideContent 1 ครั้งสำหรับที่เก็บข้อมูล DpSize แต่ละรายการ การถอดรหัส Bitmap ภายใน provideContent จะจัดสรรอินสแตนซ์ Bitmap แยกต่างหากสำหรับทุกที่เก็บ ซึ่งจะเพิ่มการใช้งานหน่วยความจำใน RemoteViews.mBitmapCache ถอดรหัสบิตแมปที่ลดอัตราสุ่ม (Bitmap.Config.RGB_565 สำหรับรูปภาพทึบแสง) 1 ครั้งภายใน provideGlance ก่อน provideContent เพื่อให้ที่เก็บข้อมูลทั้งหมดใช้การอ้างอิง Bitmap เดียวกัน
  • ใช้การนําเข้า ImageProvider ที่ตรงกัน: Jetpack Glance มีโอเวอร์โหลด ImageProvider ที่แตกต่างกัน 2 รายการใน 2 แพ็กเกจ ดังนี้

    • ใช้ import androidx.glance.ImageProvider เมื่อส่งผ่านทรัพยากร ImageProvider(bitmap: Bitmap) ในหน่วยความจำหรือทรัพยากรที่ถอนออกได้ ImageProvider(resId: Int)
    • ใช้ import androidx.glance.appwidget.ImageProvider เมื่อส่ง URI ImageProvider(uri: Uri) เมื่อแสดงไฟล์ที่แคชไว้ผ่าน URI FileProvider ให้ให้สิทธิ์ Intent.FLAG_GRANT_READ_URI_PERMISSION แก่แพ็กเกจ Launcher Intent.CATEGORY_HOME ที่ติดตั้งไว้ทุกแพ็กเกจเพื่อให้โฮสต์แสดงผลรูปภาพได้

ใช้คลาส GlanceAppWidgetReceiver เพื่อจัดการการออกอากาศวิดเจ็ต

วิดเจ็ต GlanceAppWidgetReceiver จะประสานงานการออกอากาศและการอัปเดตสถานะแพลตฟอร์มโดยการขยาย AppWidgetProvider ที่สำคัญ โดยจะรับเหตุการณ์ของแพลตฟอร์มเมื่อมีการอัปเดต ลบ เปิดใช้ หรือปิดใช้วิดเจ็ต และแปลเหตุการณ์เหล่านั้นเป็นคำขอวงจรของ Compose

ประกาศวิดเจ็ตในไฟล์ Manifest

ประกาศคลาสย่อยของคลาส GlanceAppWidgetReceiver เป็น Broadcast Receiver ในไฟล์ AndroidManifest.xml ดังนี้

<receiver android:name="MyReceiver"
          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/my_app_widget_info" />
</receiver>

องค์ประกอบ <receiver> ต้องมีแอตทริบิวต์ android:name ซึ่งระบุคลาส Receiver ตัวรับต้องยอมรับการดำเนินการประกาศ ACTION_APPWIDGET_UPDATE ภายใน <intent-filter>

องค์ประกอบ <meta-data> ต้องระบุชื่อเป็น android.appwidget.provider และแอตทริบิวต์ android:resource ต้องชี้ไปยังทรัพยากรข้อมูลเมตา XML ของ AppWidgetProviderInfo (@xml/my_app_widget_info)

ใช้คลาส GlanceAppWidgetReceiver

ใน Glance คุณจะขยาย GlanceAppWidgetReceiver แทน AppWidgetProvider โดยตรง ใช้โดยลิงก์ตัวรับสัญญาณกับอินสแตนซ์ GlanceAppWidget Callback หลักที่ใช้ได้ใน GlanceAppWidgetReceiver จะทำงานดังนี้

  • onUpdate(): Glance จะลบล้างโดยอัตโนมัติเพื่อดำเนินการอัปเดตองค์ประกอบ หากคุณลบล้าง onUpdate ด้วยตนเอง คุณต้องเรียกใช้ super.onUpdate เพื่ออนุญาตให้ Glance เปิดใช้เทรดการคอมโพสิชันได้สำเร็จ
  • onAppWidgetOptionsChanged(): เรียกใช้เมื่อวางหรือปรับขนาดวิดเจ็ตเป็นครั้งแรก Glance จะอ่านรายการแพ็กเกจตัวเลือกเบื้องหลังเพื่อให้เลย์เอาต์ปรับเปลี่ยนได้อย่างราบรื่นตามมิติข้อมูลรันไทม์
  • onDeleted(Context, IntArray): เรียกใช้เมื่อผู้ใช้ลบอินสแตนซ์วิดเจ็ตที่เฉพาะเจาะจง
  • onEnabled(Context): ทริกเกอร์เมื่อสร้างอินสแตนซ์แรกของวิดเจ็ตสำเร็จ เหมาะอย่างยิ่งสำหรับการย้ายข้อมูลทั่วโลก
  • onDisabled(Context): เรียกใช้เมื่ออินสแตนซ์ที่ใช้งานอยู่ล่าสุดของผู้ให้บริการถูกนำออก
  • onReceive(Context, Intent): ดักจับการออกอากาศของแพลตฟอร์มทุกรายการก่อนเมธอด Callback ที่เฉพาะเจาะจง คุณต้องตรวจสอบว่าตรรกะ Receiver ที่กำหนดเองที่คุณเขียนเรียก super.onReceive(context, intent) และต้องไม่เรียก goAsync ด้วยตนเอง เนื่องจาก Glance จะกำหนดเส้นทางงานแบบอะซิงโครนัสโดยอัตโนมัติ

รับ Intent การออกอากาศของวิดเจ็ต

เบื้องหลังการทำงาน GlanceAppWidgetReceiver จะกรองและจัดการ Intent การออกอากาศวิดเจ็ตแพลตฟอร์มพื้นฐานต่อไปนี้

สร้าง UI

ข้อมูลโค้ดต่อไปนี้แสดงวิธีสร้าง UI

/* Import Glance Composables
 In the event there is a name clash with the Compose classes of the same name,
 you may rename the imports per https://kotlinlang.org/docs/packages.html#imports
 using the `as` keyword.

import androidx.glance.Button
import androidx.glance.layout.Column
import androidx.glance.layout.Row
import androidx.glance.text.Text
*/
class MyAppWidget : GlanceAppWidget() {

    override suspend fun provideGlance(context: Context, id: GlanceId) {
        // Load data needed to render the AppWidget.
        // Use `withContext` to switch to another thread for long running
        // operations.

        provideContent {
            // create your AppWidget here
            MyContent()
        }
    }

    @Composable
    private fun MyContent() {
        Column(
            modifier = GlanceModifier.fillMaxSize(),
            verticalAlignment = Alignment.Top,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = "Where to?", modifier = GlanceModifier.padding(12.dp))
            Row(horizontalAlignment = Alignment.CenterHorizontally) {
                Button(
                    text = "Home",
                    onClick = actionStartActivity<MyActivity>()
                )
                Button(
                    text = "Work",
                    onClick = actionStartActivity<MyActivity>()
                )
            }
        }
    }
}

ตัวอย่างโค้ดก่อนหน้าจะทำสิ่งต่อไปนี้

  • ใน Column ระดับบนสุด รายการจะวางเรียงต่อกันในแนวตั้ง
  • Column จะขยายขนาดให้ตรงกับพื้นที่ว่าง (ผ่าน GlanceModifier และจัดแนวเนื้อหาให้อยู่ด้านบน (verticalAlignment) และจัดให้อยู่กึ่งกลางในแนวนอน (horizontalAlignment)
  • เนื้อหาของ Column จะกำหนดโดยใช้ Lambda ลำดับมีความสำคัญ
    • รายการแรกใน Column คือคอมโพเนนต์ Text ที่มีระยะห่างจากขอบ 12.dp
    • รายการที่ 2 คือ Row ซึ่งจะวางรายการต่อกันในแนวนอน โดยมี Buttons 2 รายการอยู่ตรงกลางในแนวนอน (horizontalAlignment) การแสดงผลสุดท้ายจะขึ้นอยู่กับพื้นที่ว่างที่มีอยู่ รูปภาพต่อไปนี้เป็นตัวอย่างลักษณะของข้อความแจ้ง
destination_widget
รูปที่ 1 ตัวอย่าง UI

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

ใช้มุมโค้งมน

Android 12 เปิดตัวพารามิเตอร์ของระบบเพื่อปรับแต่งรัศมีมุมของวิดเจ็ตแอปแบบไดนามิก ดังนี้

  • system_app_widget_background_radius: ระบุรัศมีมุมของคอนเทนเนอร์พื้นหลังวิดเจ็ต (ไม่เกิน 28 dp)
  • รัศมีด้านใน: เพื่อป้องกันไม่ให้เนื้อหาถูกตัด ให้คำนวณรัศมีตามสัดส่วนสำหรับเนื้อหาด้านในโดยอิงตามเส้นขอบพื้นหลังของระบบ ดังนี้ systemRadiusValue - widgetPadding

ใน Glance คุณสามารถใช้พร็อพเพอร์ตี้การปรับขนาดรัศมีมุมแบบไดนามิกในองค์ประกอบได้โดยใช้ GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius)

สำหรับความเข้ากันได้แบบย้อนหลังในอุปกรณ์ที่ใช้ Android 11 (ระดับ API 30) หรือต่ำกว่า ให้ใช้แอตทริบิวต์ที่กำหนดเองและทางเลือกสำรองของทรัพยากรธีมที่กำหนดเอง ดังนี้

  • /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>