หน้านี้อธิบายการปรับแต่งเพื่อปรับขนาดวิดเจ็ตและความยืดหยุ่นที่มากขึ้น เปิดตัวใน 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
รองรับความละเอียดตั้งแต่ 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 (118 นาที - 16) | (142n - 15) x (66 นาที - 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
ตั้งแต่ 180 dp (minResizeWidth
) x
110dp (minResizeHeight
) ถึง 269x279dp (จุดตัดถัดไปคือ 1) ในทำนองเดียวกัน
R.layout.widget_weather_forecast_medium
มีค่าตั้งแต่ 270x110dp ถึง 270x279dp
และ R.layout.widget_weather_forecast_large
ใช้ตั้งแต่ 270x280dp ถึง
530 dp (maxResizeWidth
) x 450 dp (maxResizeHeight
)
เมื่อผู้ใช้ปรับขนาดวิดเจ็ต รูปลักษณ์ของวิดเจ็ตจะเปลี่ยนไปเพื่อปรับให้เข้ากับแต่ละขนาด ดังที่ปรากฏในตัวอย่างต่อไปนี้