หน้านี้อธิบายการปรับแต่งขนาดวิดเจ็ตและความยืดหยุ่นที่มากขึ้น ซึ่งเปิดตัวใน Android 12 (API ระดับ 31) รวมถึงจะให้รายละเอียดเกี่ยวกับวิธีกำหนดขนาดสำหรับวิดเจ็ตด้วย
ใช้ API ที่ปรับปรุงแล้วสำหรับขนาดและเลย์เอาต์วิดเจ็ต
ตั้งแต่ Android 12 (API ระดับ 31) เป็นต้นไป คุณจะระบุแอตทริบิวต์ขนาดที่ละเอียดยิ่งขึ้นและเลย์เอาต์ที่ยืดหยุ่นได้โดยทำดังนี้ ตามที่อธิบายไว้ในส่วนต่างๆ ที่จะกล่าวถึงต่อไป
ใน Android เวอร์ชันก่อนหน้า คุณสามารถรับช่วงขนาดของวิดเจ็ตได้โดยใช้ส่วนเสริม OPTION_APPWIDGET_MIN_WIDTH
, OPTION_APPWIDGET_MIN_HEIGHT
, OPTION_APPWIDGET_MAX_WIDTH
และ OPTION_APPWIDGET_MAX_HEIGHT
จากนั้นจึงประมาณขนาดของวิดเจ็ต แต่ตรรกะดังกล่าวใช้ไม่ได้ในทุกสถานการณ์ สําหรับวิดเจ็ตที่กําหนดเป้าหมายเป็น Android 12 ขึ้นไป เราขอแนะนําให้
ระบุเลย์เอาต์ที่ตอบสนองหรือเลย์เอาต์ที่แน่นอน
ระบุข้อจำกัดในการปรับขนาดวิดเจ็ตเพิ่มเติม
Android 12 เพิ่ม API ที่ช่วยให้คุณมั่นใจได้ว่าวิดเจ็ตจะมีขนาดที่เชื่อถือได้มากขึ้นในอุปกรณ์ต่างๆ ที่มีขนาดหน้าจอแตกต่างกัน
นอกเหนือจากแอตทริบิวต์ minWidth
,
minHeight
,
minResizeWidth
,
และ minResizeHeight
ที่มีอยู่แล้ว ให้ใช้แอตทริบิวต์ appwidget-provider
ใหม่ต่อไปนี้
targetCellWidth
และtargetCellHeight
กำหนดขนาดเป้าหมายของวิดเจ็ตในแง่ของเซลล์ตารางกริดของ Launcher หากมีการกำหนดไว้ ระบบจะใช้แอตทริบิวต์เหล่านี้แทนminWidth
หรือminHeight
maxResizeWidth
และmaxResizeHeight
กําหนดขนาดสูงสุดที่ตัวเรียกใช้จะอนุญาตให้ผู้ใช้ปรับขนาดวิดเจ็ต
XML ต่อไปนี้แสดงวิธีใช้แอตทริบิวต์การกำหนดขนาด
<appwidget-provider
...
android:targetCellWidth="3"
android:targetCellHeight="2"
android:maxResizeWidth="250dp"
android:maxResizeHeight="110dp">
</appwidget-provider>
ระบุเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์
หากจำเป็นต้องเปลี่ยนเลย์เอาต์ตามขนาดของวิดเจ็ต เราขอแนะนำให้ สร้างเลย์เอาต์ชุดเล็กๆ โดยแต่ละเลย์เอาต์จะใช้ได้กับขนาดที่หลากหลาย หากทำไม่ได้ อีกทางเลือกหนึ่งคือการระบุเลย์เอาต์ตามขนาดวิดเจ็ตที่แน่นอน ในเวลาเรียกใช้ ตามที่อธิบายไว้ในหน้านี้
ฟีเจอร์นี้ช่วยให้การปรับขนาดราบรื่นขึ้นและระบบโดยรวมมีประสิทธิภาพดีขึ้น เนื่องจากระบบไม่ต้องปลุกแอปทุกครั้ง ที่แสดงวิดเจ็ตในขนาดที่ต่างกัน
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีระบุรายการเลย์เอาต์
Kotlin
override fun onUpdate(...) { val smallView = ... val tallView = ... val wideView = ... val viewMapping: Map<SizeF, RemoteViews> = mapOf( SizeF(150f, 100f) to smallView, SizeF(150f, 200f) to tallView, SizeF(215f, 100f) to wideView ) val remoteViews = RemoteViews(viewMapping) appWidgetManager.updateAppWidget(id, remoteViews) }
Java
@Override public void onUpdate(...) { RemoteViews smallView = ...; RemoteViews tallView = ...; RemoteViews wideView = ...; Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>(); viewMapping.put(new SizeF(150f, 100f), smallView); viewMapping.put(new SizeF(150f, 200f), tallView); viewMapping.put(new SizeF(215f, 100f), wideView); RemoteViews remoteViews = new RemoteViews(viewMapping); appWidgetManager.updateAppWidget(id, remoteViews); }
สมมติว่าวิดเจ็ตมีแอตทริบิวต์ต่อไปนี้
<appwidget-provider
android:minResizeWidth="160dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="250dp"
android:maxResizeHeight="200dp">
</appwidget-provider>
ข้อมูลโค้ดข้างต้นมีความหมายดังนี้
smallView
รองรับตั้งแต่ 160dp (minResizeWidth
) × 110dp (minResizeHeight
) ไปจนถึง 160dp × 199dp (จุดตัดถัดไป - 1dp)tallView
รองรับตั้งแต่ 160dp × 200dp ถึง 214dp (จุดตัดถัดไป - 1) × 200dpwideView
รองรับตั้งแต่ 215dp × 110dp (minResizeHeight
) ไปจนถึง 250dp (maxResizeWidth
) × 200dp (maxResizeHeight
)
วิดเจ็ตต้องรองรับช่วงขนาดตั้งแต่ minResizeWidth
×
minResizeHeight
ถึง maxResizeWidth
× maxResizeHeight
ภายในช่วงนั้น
คุณสามารถกำหนดจุดตัดเพื่อสลับเลย์เอาต์ได้

ระบุเลย์เอาต์ที่แน่นอน
หากไม่สามารถใช้เลย์เอาต์ที่ปรับเปลี่ยนตามพื้นที่โฆษณาจำนวนเล็กน้อยได้ คุณสามารถระบุเลย์เอาต์อื่นที่ปรับให้เหมาะกับขนาดที่วิดเจ็ตแสดงแทนได้ โดยปกติแล้วจะมี 2 ขนาดสำหรับโทรศัพท์ (โหมดแนวตั้งและแนวนอน) และ 4 ขนาดสำหรับ อุปกรณ์พับได้
หากต้องการใช้โซลูชันนี้ แอปของคุณต้องทำตามขั้นตอนต่อไปนี้
โอเวอร์โหลด
AppWidgetProvider.onAppWidgetOptionsChanged()
, ซึ่งจะเรียกใช้เมื่อชุดขนาดมีการเปลี่ยนแปลงเรียกใช้
AppWidgetManager.getAppWidgetOptions()
ซึ่งจะแสดงBundle
ที่มีขนาดเข้าถึงคีย์
AppWidgetManager.OPTION_APPWIDGET_SIZES
จากBundle
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีระบุเลย์เอาต์ที่แน่นอน
Kotlin
override fun onAppWidgetOptionsChanged( context: Context, appWidgetManager: AppWidgetManager, id: Int, newOptions: Bundle? ) { super.onAppWidgetOptionsChanged(context, appWidgetManager, id, newOptions) // Get the new sizes. val sizes = newOptions?.getParcelableArrayList<SizeF>( AppWidgetManager.OPTION_APPWIDGET_SIZES ) // Check that the list of sizes is provided by the launcher. if (sizes.isNullOrEmpty()) { return } // Map the sizes to the RemoteViews that you want. val remoteViews = RemoteViews(sizes.associateWith(::createRemoteViews)) appWidgetManager.updateAppWidget(id, remoteViews) } // Create the RemoteViews for the given size. private fun createRemoteViews(size: SizeF): RemoteViews { }
Java
@Override public void onAppWidgetOptionsChanged( Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); // Get the new sizes. ArrayList<SizeF> sizes = newOptions.getParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES); // Check that the list of sizes is provided by the launcher. if (sizes == null || sizes.isEmpty()) { return; } // Map the sizes to the RemoteViews that you want. Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>(); for (SizeF size : sizes) { viewMapping.put(size, createRemoteViews(size)); } RemoteViews remoteViews = new RemoteViews(viewMapping); appWidgetManager.updateAppWidget(id, remoteViews); } // Create the RemoteViews for the given size. private RemoteViews createRemoteViews(SizeF size) { }
กำหนดขนาดวิดเจ็ต
วิดเจ็ตแต่ละรายการต้องกําหนด targetCellWidth
และ targetCellHeight
สําหรับอุปกรณ์ที่ใช้ Android 12 ขึ้นไป หรือ minWidth
และ minHeight
สําหรับ Android ทุกเวอร์ชัน ซึ่งระบุพื้นที่ขั้นต่ำที่ใช้โดยค่าเริ่มต้น
อย่างไรก็ตาม เมื่อผู้ใช้เพิ่มวิดเจ็ตลงในหน้าจอหลัก วิดเจ็ตมักจะ
ใช้พื้นที่มากกว่าความกว้างและความสูงขั้นต่ำที่คุณระบุ
หน้าจอหลักของ Android จะแสดงตารางพื้นที่ว่างให้ผู้ใช้
วางวิดเจ็ตและไอคอน ตารางกริดนี้อาจแตกต่างกันไปตามอุปกรณ์ เช่น โทรศัพท์มือถือหลายรุ่นมีตารางกริด 5x4 และแท็บเล็ตอาจมีตารางกริดที่ใหญ่กว่า เมื่อเพิ่มวิดเจ็ต ระบบจะขยายวิดเจ็ตให้ครอบคลุมจำนวนเซลล์ขั้นต่ำ
ทั้งในแนวนอนและแนวตั้งตามที่จำเป็นเพื่อให้เป็นไปตามข้อจำกัดสำหรับ targetCellWidth
และ targetCellHeight
ในอุปกรณ์ที่ใช้
Android 12 ขึ้นไป หรือข้อจำกัด minWidth
และ minHeight
ในอุปกรณ์ที่ใช้
Android 11 (API ระดับ 30) ลงไป
ทั้งความกว้างและความสูงของเซลล์และขนาดของระยะขอบอัตโนมัติที่ใช้กับวิดเจ็ตอาจแตกต่างกันไปในแต่ละอุปกรณ์ ใช้ตารางต่อไปนี้เพื่อประมาณขนาดขั้นต่ำของวิดเจ็ต ในโทรศัพท์มือถือแบบตารางกริด 5x4 ทั่วไป โดยพิจารณาจาก จำนวนเซลล์กริดที่ต้องการใช้
จำนวนเซลล์ (กว้าง x สูง) | ขนาดที่ใช้ได้ในโหมดแนวตั้ง (dp) | ขนาดที่ใช้ได้ในโหมดแนวนอน (dp) |
---|---|---|
1x1 | 57x102dp | 127x51dp |
2x1 | 130x102dp | 269x51dp |
3x1 | 203x102dp | 412x51dp |
4x1 | 276x102dp | 554x51dp |
5x1 | 349x102dp | 697x51dp |
5x2 | 349x220dp | 697x117dp |
5x3 | 349x337dp | 697x184dp |
5x4 | 349x455dp | 697x250dp |
... | ... | ... |
n x m | (73n - 16) x (118m - 16) | (142n - 15) x (66m - 15) |
ใช้ขนาดเซลล์โหมดแนวตั้งเพื่อแจ้งค่าที่คุณระบุสำหรับแอตทริบิวต์
minWidth
, minResizeWidth
และ maxResizeWidth
ในทำนองเดียวกัน
ให้ใช้ขนาดเซลล์ในโหมดแนวนอนเพื่อเป็นข้อมูลสำหรับค่าที่คุณระบุ
สำหรับแอตทริบิวต์ minHeight
, minResizeHeight
และ maxResizeHeight
สาเหตุคือโดยปกติแล้วความกว้างของเซลล์ในโหมดแนวตั้งจะน้อยกว่าในโหมดแนวนอน และในทำนองเดียวกัน ความสูงของเซลล์ในโหมดแนวนอนจะน้อยกว่าในโหมดแนวตั้ง
ตัวอย่างเช่น หากต้องการให้ความกว้างของวิดเจ็ตปรับขนาดลงได้ถึง 1 เซลล์ใน
Google Pixel 4 คุณต้องตั้งค่า minResizeWidth
ไม่เกิน 56dp
เพื่อให้แน่ใจว่าค่าของแอตทริบิวต์ minResizeWidth
มีขนาดเล็กกว่า
57dp เนื่องจากเซลล์มีความกว้างอย่างน้อย 57dp ในแนวตั้ง
ในทำนองเดียวกัน หากต้องการให้ปรับความสูงของวิดเจ็ตในเซลล์เดียวบนอุปกรณ์เดียวกันได้ คุณต้องตั้งค่า minResizeHeight
ไม่เกิน 50dp เพื่อให้แน่ใจว่าค่าของแอตทริบิวต์ minResizeHeight
มีค่าน้อยกว่า 51dp เนื่องจากเซลล์เดียวมีความสูงอย่างน้อย 51dp ในโหมดแนวนอน
วิดเจ็ตแต่ละรายการสามารถปรับขนาดได้ภายในช่วงขนาดระหว่างแอตทริบิวต์
minResizeWidth
/minResizeHeight
และ maxResizeWidth
/maxResizeHeight
ซึ่งหมายความว่าวิดเจ็ตต้องปรับให้เข้ากับช่วงขนาดใดก็ได้ระหว่างแอตทริบิวต์ดังกล่าว
ตัวอย่างเช่น หากต้องการตั้งค่าขนาดเริ่มต้นของวิดเจ็ตในตําแหน่ง คุณสามารถ ตั้งค่าแอตทริบิวต์ต่อไปนี้ได้
<appwidget-provider
android:targetCellWidth="3"
android:targetCellHeight="2"
android:minWidth="180dp"
android:minHeight="110dp">
</appwidget-provider>
ซึ่งหมายความว่าขนาดเริ่มต้นของวิดเจ็ตคือ 3x2 เซลล์ ตามที่ระบุโดยแอตทริบิวต์
targetCellWidth
และ targetCellHeight
หรือ 180×110dp ตามที่ระบุโดย minWidth
และ minHeight
สำหรับอุปกรณ์ที่ใช้
Android 11 หรือต่ำกว่า ในกรณีหลัง ขนาดในเซลล์อาจ
แตกต่างกันไปตามอุปกรณ์
นอกจากนี้ หากต้องการตั้งค่าช่วงขนาดที่รองรับของวิดเจ็ต คุณสามารถตั้งค่าแอตทริบิวต์ต่อไปนี้ได้
<appwidget-provider
android:minResizeWidth="180dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="530dp"
android:maxResizeHeight="450dp">
</appwidget-provider>
ตามที่ระบุไว้ในแอตทริบิวต์ก่อนหน้า ความกว้างของวิดเจ็ตสามารถ ปรับขนาดได้ตั้งแต่ 180dp ถึง 530dp และความสูงสามารถปรับขนาดได้ตั้งแต่ 110dp ถึง 450dp จากนั้นคุณจะปรับขนาดวิดเจ็ตจาก 3x2 เป็น 5x2 เซลล์ได้ตราบใดที่มีเงื่อนไขต่อไปนี้
- อุปกรณ์มีตารางกริด 5x4
- การแมประหว่างจำนวนเซลล์กับขนาดที่ใช้ได้ในหน่วย dps เป็นไปตามตารางที่แสดงการประมาณขนาดขั้นต่ำในหน้านี้
- วิดเจ็ตจะปรับให้เข้ากับช่วงขนาดดังกล่าว
Kotlin
val smallView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_small) val mediumView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_medium) val largeView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_large) val viewMapping: Map<SizeF, RemoteViews> = mapOf( SizeF(180f, 110f) to smallView, SizeF(270f, 110f) to mediumView, SizeF(270f, 280f) to largeView ) appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(viewMapping))
Java
RemoteViews smallView = new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_small); RemoteViews mediumView = new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_medium); RemoteViews largeView = new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_large); Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>(); viewMapping.put(new SizeF(180f, 110f), smallView); viewMapping.put(new SizeF(270f, 110f), mediumView); viewMapping.put(new SizeF(270f, 280f), largeView); RemoteViews remoteViews = new RemoteViews(viewMapping); appWidgetManager.updateAppWidget(id, remoteViews);
สมมติว่าวิดเจ็ตใช้เลย์เอาต์ที่ตอบสนองที่กำหนดไว้ในข้อมูลโค้ดก่อนหน้า
ซึ่งหมายความว่าเลย์เอาต์ที่ระบุเป็น
R.layout.widget_weather_forecast_small
จะใช้ตั้งแต่ 180dp (minResizeWidth
) x
110dp (minResizeHeight
) ไปจนถึง 269x279dp (จุดตัดถัดไป - 1) ในทำนองเดียวกัน
R.layout.widget_weather_forecast_medium
จะใช้ตั้งแต่ 270x110dp ถึง 270x279dp
และ R.layout.widget_weather_forecast_large
จะใช้ตั้งแต่ 270x280dp ถึง
530dp (maxResizeWidth
) x 450dp (maxResizeHeight
)
เมื่อผู้ใช้ปรับขนาดวิดเจ็ต ลักษณะที่ปรากฏจะเปลี่ยนไปเพื่อให้เหมาะกับแต่ละขนาดใน เซลล์ ดังที่แสดงในตัวอย่างต่อไปนี้

R.layout.widget_weather_forecast_small

R.layout.widget_weather_forecast_medium

R.layout.widget_weather_forecast_medium
.
R.layout.widget_weather_forecast_large
.
R.layout.widget_weather_forecast_large
.