รองรับเนื้อหาที่ผู้ใช้ปรับขนาดได้

ใช้ท่าทางสัมผัสบีบเพื่อซูมเพื่อรองรับเนื้อหาที่ปรับขนาดได้ในแอป ซึ่งเป็นวิธีมาตรฐานที่สอดคล้องกับแพลตฟอร์มในการปรับปรุงการช่วยเหลือพิเศษ ช่วยให้ผู้ใช้ปรับขนาดข้อความและองค์ประกอบ 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 ของคุณกับการปรับขนาดในแอปและการตั้งค่าแบบอักษรหรือการแสดงผลทั่วทั้งระบบ ตรวจสอบว่าเลย์เอาต์ของแอปปรับเปลี่ยนได้อย่างถูกต้องโดยไม่ทำให้เนื้อหาเสียหาย ทับซ้อนกัน หรือซ่อนอยู่ ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีสร้างเลย์เอาต์แบบปรับอัตโนมัติ