หน้านี้อธิบายการปรับแต่งเพื่อปรับขนาดวิดเจ็ตและความยืดหยุ่นที่มากขึ้น เปิดตัวใน 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
: กำหนดขนาดสูงสุดที่ Launcher อนุญาตให้ผู้ใช้ปรับขนาดวิดเจ็ต
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
รองรับตั้งแต่ 160 dp (minResizeWidth
) × 110 dp (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 |
... | ... | ... |
กว้าง x ม. | (73n - 16) x (118m - 16) | (142n - 15) x (66m - 15) |
ใช้ขนาดเซลล์ในโหมดแนวตั้งเพื่อแจ้งค่าที่คุณระบุสำหรับ
แอตทริบิวต์ minWidth
, minResizeWidth
และ maxResizeWidth
ในทำนองเดียวกัน ให้ใช้ขนาดเซลล์ในโหมดแนวนอนเพื่อระบุค่าที่คุณระบุสำหรับแอตทริบิวต์ minHeight
, minResizeHeight
และ maxResizeHeight
เนื่องจากโดยทั่วไปแล้วความกว้างของเซลล์จะน้อยกว่าในโหมดแนวตั้ง เมื่อเทียบกับโหมดแนวนอน และในทำนองเดียวกัน ความสูงของเซลล์มักจะ ในโหมดแนวนอนจะมีขนาดเล็กกว่าในโหมดแนวตั้ง
ตัวอย่างเช่น หากคุณต้องการปรับขนาดความกว้างของวิดเจ็ตให้เล็กลงเหลือเพียงเซลล์เดียว
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