สัญญาณบอกสถานะความคืบหน้า

สัญญาณบอกสถานะความคืบหน้าจะแสดงสถานะการทำงานด้วยภาพ โดยใช้การเคลื่อนไหวเพื่อดึงดูดความสนใจของผู้ใช้ว่ากระบวนการดังกล่าวใกล้จะเสร็จสมบูรณ์แล้ว เช่น การโหลดหรือการประมวลผลข้อมูล นอกจากนี้ยังสามารถบ่งบอกว่ามีการประมวลผลเกิดขึ้นโดยไม่ระบุว่าใกล้จะเสร็จสมบูรณ์มากน้อยเพียงใด

ลองพิจารณากรณีการใช้งาน 3 แบบต่อไปนี้ที่คุณอาจใช้สัญญาณบอกสถานะความคืบหน้า

  • การโหลดเนื้อหา: ขณะดึงเนื้อหาจากเครือข่าย เช่น การโหลด รูปภาพหรือข้อมูลสำหรับโปรไฟล์ผู้ใช้
  • การอัปโหลดไฟล์: ให้ความคิดเห็นแก่ผู้ใช้เกี่ยวกับระยะเวลาที่อาจใช้ในการอัปโหลด
  • การประมวลผลที่ใช้เวลานาน: ขณะที่แอปกำลังประมวลผลข้อมูลจำนวนมาก ให้บอกผู้ใช้ว่าประมวลผลเสร็จไปแล้วเท่าใดจากทั้งหมด

ใน Material Design สัญญาณบอกสถานะความคืบหน้ามี 2 ประเภท ได้แก่

  • กำหนดได้: แสดงความคืบหน้าอย่างแม่นยำ
  • กำหนดไม่ได้: แสดงภาพเคลื่อนไหวอย่างต่อเนื่องโดยไม่คำนึงถึงความคืบหน้า

เช่นเดียวกัน สัญญาณบอกสถานะความคืบหน้าสามารถใช้รูปแบบใดรูปแบบหนึ่งต่อไปนี้

  • เชิงเส้น: แถบแนวนอนที่เติมจากซ้ายไปขวา
  • วงกลม: วงกลมที่มีเส้นขีดเพิ่มความยาวจนครอบคลุม เส้นรอบวงทั้งหมดของวงกลม
สัญญาณบอกสถานะความคืบหน้าแบบเชิงเส้นควบคู่ไปกับสัญญาณบอกสถานะความคืบหน้าแบบวงกลม
รูปที่ 1 สัญญาณบอกสถานะความคืบหน้า 2 ประเภท

แพลตฟอร์ม API

แม้ว่าจะมี Composable หลายรายการที่คุณใช้สร้างสัญญาณบอกสถานะความคืบหน้าที่สอดคล้องกับ Material Design ได้ แต่พารามิเตอร์ของ Composable เหล่านั้นไม่ได้แตกต่างกันมากนัก พารามิเตอร์หลักที่คุณควรทราบมีดังนี้

  • progress: ความคืบหน้าปัจจุบันที่สัญญาณบอกสถานะแสดง ส่งค่า Float ระหว่าง 0.0 ถึง 1.0
  • color: สีของสัญญาณบอกสถานะจริง นั่นคือ ส่วนของคอมโพเนนต์ที่แสดงความคืบหน้าและครอบคลุมคอมโพเนนต์ทั้งหมดเมื่อความคืบหน้าเสร็จสมบูรณ์
  • trackColor: สีของแทร็กที่วาดสัญญาณบอกสถานะ

สัญญาณบอกสถานะที่กำหนดได้

สัญญาณบอกสถานะที่กำหนดได้จะแสดงความสมบูรณ์ของการดำเนินการอย่างแม่นยำ ใช้ Composable LinearProgressIndicator หรือ CircularProgressIndicator และส่งค่าสำหรับพารามิเตอร์ progress

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างที่ค่อนข้างละเอียด เมื่อผู้ใช้กดปุ่ม แอปจะแสดงสัญญาณบอกสถานะความคืบหน้าและเปิดใช้ Coroutine ที่ค่อยๆ เพิ่มค่า progress ซึ่งจะทำให้สัญญาณบอกสถานะความคืบหน้าวนซ้ำขึ้น

@Composable
fun LinearDeterminateIndicator() {
    var currentProgress by remember { mutableFloatStateOf(0f) }
    var loading by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope() // Create a coroutine scope

    Column(
        verticalArrangement = Arrangement.spacedBy(12.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxWidth()
    ) {
        Button(onClick = {
            loading = true
            scope.launch {
                loadProgress { progress ->
                    currentProgress = progress
                }
                loading = false // Reset loading when the coroutine finishes
            }
        }, enabled = !loading) {
            Text("Start loading")
        }

        if (loading) {
            LinearProgressIndicator(
                progress = { currentProgress },
                modifier = Modifier.fillMaxWidth(),
            )
        }
    }
}

/** Iterate the progress value */
suspend fun loadProgress(updateProgress: (Float) -> Unit) {
    for (i in 1..100) {
        updateProgress(i.toFloat() / 100)
        delay(100)
    }
}

เมื่อการโหลดเสร็จสมบูรณ์บางส่วน สัญญาณบอกสถานะเชิงเส้นในตัวอย่างก่อนหน้าจะปรากฏดังนี้

ในทำนองเดียวกัน สัญญาณบอกสถานะแบบวงกลมจะปรากฏดังนี้

สัญญาณบอกสถานะที่กำหนดไม่ได้

สัญญาณบอกสถานะที่กำหนดไม่ได้จะไม่แสดงว่าการดำเนินการใกล้จะเสร็จสมบูรณ์มากน้อยเพียงใด แต่จะใช้การเคลื่อนไหวเพื่อบ่งบอกให้ผู้ใช้ทราบว่ามีการประมวลผลเกิดขึ้นโดยไม่ระบุระดับความสมบูรณ์

หากต้องการสร้างสัญญาณบอกสถานะความคืบหน้าที่กำหนดไม่ได้ ให้ใช้ Composable LinearProgressIndicator หรือ CircularProgressIndicator แต่ไม่ต้องส่งค่าสำหรับ progress ตัวอย่างต่อไปนี้แสดงวิธีสลับสัญญาณบอกสถานะที่กำหนดไม่ได้ด้วยการกดปุ่ม

@Composable
fun IndeterminateCircularIndicator() {
    var loading by remember { mutableStateOf(false) }

    Button(onClick = { loading = true }, enabled = !loading) {
        Text("Start loading")
    }

    if (!loading) return

    CircularProgressIndicator(
        modifier = Modifier.width(64.dp),
        color = MaterialTheme.colorScheme.secondary,
        trackColor = MaterialTheme.colorScheme.surfaceVariant,
    )
}

ตัวอย่างการติดตั้งใช้งานนี้เมื่อสัญญาณบอกสถานะทำงานอยู่

ตัวอย่างการติดตั้งใช้งานเดียวกันนี้แต่ใช้ LinearProgressIndicator แทน CircularProgressIndicator

แหล่งข้อมูลเพิ่มเติม