ใช้ท่าทางสัมผัสบีบเพื่อซูมเพื่อรองรับเนื้อหาที่ปรับขนาดได้ในแอป ซึ่งเป็นวิธีมาตรฐานที่สอดคล้องกับแพลตฟอร์มในการปรับปรุงการช่วยเหลือพิเศษ ช่วยให้ผู้ใช้ปรับขนาดข้อความและองค์ประกอบ UI ให้เหมาะกับความต้องการได้อย่างง่ายดาย แอปของคุณสามารถกำหนดลักษณะการปรับขนาดที่กำหนดเองด้วยการควบคุมแบบละเอียดและลักษณะตามบริบท ซึ่งจะมอบประสบการณ์ที่ผู้ใช้มักจะค้นพบได้เร็วกว่าฟีเจอร์ระดับระบบ เช่น การขยายหน้าจอ
เลือกกลยุทธ์การปรับขนาด
กลยุทธ์ที่กล่าวถึงในคู่มือนี้จะทำให้ UI ปรับเปลี่ยนและจัดระเบียบใหม่เพื่อให้พอดีกับความกว้างของหน้าจอ ซึ่งจะช่วยเพิ่มประโยชน์ด้านการช่วยเหลือพิเศษอย่างมากโดยไม่จำเป็นต้องเลื่อนในแนวนอนและไม่ต้องเคลื่อนไหวแบบ "ซิกแซก" ที่น่าหงุดหงิดซึ่งจำเป็นต่อการอ่านข้อความยาวๆ
อ่านเพิ่มเติม: งานวิจัยยืนยันว่าสำหรับผู้ใช้ที่มีสายตาเลือนราง เนื้อหาที่จัดเรียงใหม่จะอ่านได้ง่ายกว่าและไปยังส่วนต่างๆ ได้ง่ายกว่าอินเทอร์เฟซที่ต้องเลื่อนแบบ 2 มิติอย่างมาก ดูรายละเอียดเพิ่มเติมได้ที่การเปรียบเทียบเนื้อหาแบบเลื่อนและสแกนกับเนื้อหาที่ปรับขนาดได้บนอุปกรณ์เคลื่อนที่
ปรับขนาดองค์ประกอบทั้งหมดหรือเฉพาะองค์ประกอบของข้อความ
ตารางต่อไปนี้แสดงผลลัพธ์ที่มองเห็นได้ของกลยุทธ์การปรับขนาดแต่ละแบบ
| กลยุทธ์ | การปรับขนาดความหนาแน่น | การปรับขนาดแบบอักษร |
|---|---|---|
พฤติกรรม |
ปรับขนาดทุกอย่างตามสัดส่วน เนื้อหาจะจัดเรียงใหม่ให้พอดีกับคอนเทนเนอร์ เพื่อให้ผู้ใช้ไม่ต้องเลื่อนในแนวนอนเพื่อดูเนื้อหาทั้งหมด |
มีผลกับองค์ประกอบของข้อความเท่านั้น เลย์เอาต์โดยรวมและองค์ประกอบที่ไม่ใช่ข้อความจะยังคงมีขนาดเท่าเดิม |
What Scales |
องค์ประกอบภาพทั้งหมด: ข้อความ คอมโพเนนต์ (ปุ่ม ไอคอน) รูปภาพ และระยะห่างของเลย์เอาต์ (ระยะห่างจากขอบ ระยะขอบ) |
ข้อความเท่านั้น |
การสาธิต |
คำแนะนำ
เมื่อได้เห็นความแตกต่างด้านภาพแล้ว ตารางต่อไปนี้จะช่วยให้คุณพิจารณาข้อดีข้อเสียและเลือกกลยุทธ์ที่ดีที่สุดสำหรับเนื้อหาของคุณ
ประเภท UI |
กลยุทธ์ที่แนะนํา |
การให้เหตุผล |
เลย์เอาต์ที่เน้นการอ่าน ตัวอย่าง: บทความข่าว แอปรับส่งข้อความ |
ความหนาแน่นหรือการปรับขนาดแบบอักษร |
เราขอแนะนำให้ใช้การปรับขนาดความหนาแน่นเพื่อปรับขนาดพื้นที่เนื้อหาทั้งหมด รวมถึงรูปภาพในบรรทัด การปรับขนาดแบบอักษรเป็นทางเลือกที่ตรงไปตรงมาหากต้องการปรับขนาดเฉพาะข้อความเท่านั้น |
เลย์เอาต์ที่มีโครงสร้างภาพ ตัวอย่าง: App Store, ฟีดโซเชียลมีเดีย |
การปรับขนาดความหนาแน่น |
คงความสัมพันธ์ด้านภาพระหว่างรูปภาพและข้อความในภาพสไลด์หรือตารางกริด ลักษณะการจัดเรียงใหม่จะช่วยหลีกเลี่ยงการเลื่อนในแนวนอน ซึ่งจะขัดแย้งกับองค์ประกอบการเลื่อนที่ฝังอยู่ |
ตรวจจับท่าทางสัมผัสการปรับขนาดใน Jetpack Compose
หากต้องการรองรับเนื้อหาที่ผู้ใช้ปรับขนาดได้ คุณต้องตรวจจับท่าทางสัมผัสแบบมัลติทัชก่อน ใน Jetpack Compose คุณสามารถทำได้โดยใช้ Modifier.transformable
ตัวแก้ไข transformable เป็น API ระดับสูงที่ให้zoomChange
เดลต้า ตั้งแต่เหตุการณ์ท่าทางสัมผัสล่าสุด ซึ่งจะช่วยลดความซับซ้อนของตรรกะการอัปเดตสถานะเป็นการสะสมโดยตรง (เช่น scale *= zoomChange) จึงเหมาะอย่างยิ่งสำหรับกลยุทธ์การปรับขนาดแบบปรับอัตโนมัติที่ครอบคลุมในคู่มือนี้
ตัวอย่างการใช้งาน
ตัวอย่างต่อไปนี้แสดงวิธีใช้กลยุทธ์การปรับขนาดความหนาแน่นและการปรับขนาดแบบอักษร
การปรับขนาดความหนาแน่น
วิธีนี้จะปรับขนาด density พื้นฐานของพื้นที่ UI ด้วยเหตุนี้ การวัดผลตามเลย์เอาต์ทั้งหมด ซึ่งรวมถึงระยะห่างจากขอบ ระยะห่าง และขนาดคอมโพเนนต์ จะปรับขนาดราวกับว่าขนาดหรือความละเอียดของหน้าจอมีการเปลี่ยนแปลง เนื่องจากขนาดข้อความยังขึ้นอยู่กับความหนาแน่นด้วย จึงปรับขนาดตามสัดส่วนด้วย กลยุทธ์นี้มีประสิทธิภาพเมื่อคุณต้องการขยายองค์ประกอบทั้งหมดภายในพื้นที่ที่เฉพาะเจาะจงอย่างสม่ำเสมอ โดยยังคงจังหวะและสัดส่วนภาพโดยรวมของ UI ไว้
private class DensityScalingState( // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x. private val minScale: Float = 0.75f, private val maxScale: Float = 3.5f, private val currentDensity: Density ) { val transformableState = TransformableState { zoomChange, _, _ -> scaleFactor.floatValue = (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale) } val scaleFactor = mutableFloatStateOf(1f) fun scaledDensity(): Density { return Density( currentDensity.density * scaleFactor.floatValue, currentDensity.fontScale ) } } @Composable fun DensityScalingSample() { val currentDensity = LocalDensity.current val scaleState = remember(currentDensity) { DensityScalingState(currentDensity = currentDensity) } Box( modifier = Modifier .fillMaxSize() .transformable(state = scaleState.transformableState), contentAlignment = Alignment.TopCenter ) { CompositionLocalProvider( LocalDensity provides scaleState.scaledDensity() ) { DemoCard() } } }
การปรับขนาดแบบอักษร
กลยุทธ์นี้มีการกำหนดเป้าหมายมากขึ้น โดยแก้ไขเฉพาะปัจจัย fontScale ผลลัพธ์ที่ได้คือมีเพียงองค์ประกอบของข้อความเท่านั้นที่ขยายหรือย่อ ในขณะที่คอมโพเนนต์เลย์เอาต์อื่นๆ ทั้งหมด เช่น คอนเทนเนอร์ ระยะห่างจากขอบ และไอคอน จะยังคงมีขนาดคงที่ กลยุทธ์นี้เหมาะอย่างยิ่งสำหรับการปรับปรุงความชัดเจนในการอ่านข้อความในแอปที่เน้นการอ่าน
class FontScaleState( // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x. private val minScale: Float = 0.75f, private val maxScale: Float = 3.5f, private val currentDensity: Density ) { val transformableState = TransformableState { zoomChange, _, _ -> scaleFactor.floatValue = (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale) } val scaleFactor = mutableFloatStateOf(1f) fun scaledFont(): Density { return Density( currentDensity.density, currentDensity.fontScale * scaleFactor.floatValue ) } } @Composable fun FontScalingSample() { val currentDensity = LocalDensity.current val scaleState = remember { FontScaleState(currentDensity = currentDensity) } Box( modifier = Modifier .fillMaxSize() .transformable(state = scaleState.transformableState), contentAlignment = Alignment.TopCenter ) { CompositionLocalProvider( LocalDensity provides scaleState.scaledFont() ) { DemoCard() } } }
UI สาธิตที่แชร์
นี่คือ Composable DemoCard ที่ใช้ร่วมกันซึ่งใช้โดยทั้ง 2 ตัวอย่างก่อนหน้านี้เพื่อไฮไลต์ลักษณะการปรับขนาดที่แตกต่างกัน
@Composable private fun DemoCard() { Card( modifier = Modifier .width(360.dp) .padding(16.dp), shape = RoundedCornerShape(12.dp) ) { Column( modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { Text("Demo Card", style = MaterialTheme.typography.headlineMedium) var isChecked by remember { mutableStateOf(true) } Row(verticalAlignment = Alignment.CenterVertically) { Text("Demo Switch", Modifier.weight(1f), style = MaterialTheme.typography.bodyLarge) Switch(checked = isChecked, onCheckedChange = { isChecked = it }) } Row(verticalAlignment = Alignment.CenterVertically) { Icon(Icons.Filled.Person, "Icon", Modifier.size(32.dp)) Spacer(Modifier.width(8.dp)) Text("Demo Icon", style = MaterialTheme.typography.bodyLarge) } Row( Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { Box( Modifier .width(100.dp) .weight(1f) .height(80.dp) .background(Color.Blue) ) Box( Modifier .width(100.dp) .weight(1f) .height(80.dp) .background(Color.Red) ) } Text( "Demo Text: Lorem ipsum dolor sit amet, consectetur adipiscing elit," + " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", style = MaterialTheme.typography.bodyMedium, textAlign = TextAlign.Justify ) } } }
เคล็ดลับและข้อควรพิจารณา
พิจารณาคำแนะนำต่อไปนี้เพื่อสร้างประสบการณ์การใช้งานที่สมบูรณ์และเข้าถึงได้ง่ายยิ่งขึ้น
- พิจารณาเสนอการควบคุมการปรับขนาดที่ไม่ใช้ท่าทางสัมผัส: ผู้ใช้บางรายอาจมีปัญหาในการใช้ท่าทางสัมผัส เพื่อช่วยเหลือผู้ใช้เหล่านี้ ให้พิจารณาจัดหาวิธีอื่นในการปรับหรือรีเซ็ตสเกลที่ไม่ต้องใช้ท่าทางสัมผัส
- สร้างขึ้นเพื่อรองรับทุกขนาด: ทดสอบ UI ของคุณกับการปรับขนาดในแอปและการตั้งค่าแบบอักษรหรือการแสดงผลทั่วทั้งระบบ ตรวจสอบว่าเลย์เอาต์ของแอปปรับเปลี่ยนได้อย่างถูกต้องโดยไม่ทำให้เนื้อหาเสียหาย ทับซ้อนกัน หรือซ่อนอยู่ ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีสร้างเลย์เอาต์แบบปรับอัตโนมัติ