ปุ่มไอคอน

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

ปุ่มไอคอนมี 2 ประเภท ได้แก่

  • เริ่มต้น: ปุ่มเหล่านี้สามารถเปิดองค์ประกอบอื่นๆ เช่น เมนูหรือการค้นหา
  • เปิด/ปิด: ปุ่มเหล่านี้อาจแสดงการดำเนินการแบบ 2 ค่าที่เปิดหรือปิดได้ เช่น "รายการโปรด" หรือ "บุ๊กมาร์ก"
ปุ่มไอคอน 5 ปุ่มที่มีไอคอนต่างกัน (การตั้งค่า เพิ่มเติม ฯลฯ) บางรายการเป็นสี่เหลี่ยมผืนผ้าที่เต็มพื้นที่ ซึ่งบ่งบอกว่ามีการเลือก และบางรายการเป็นสี่เหลี่ยมผืนผ้าที่มีเส้นขอบ
รูปที่ 1 ปุ่มไอคอนบางปุ่มมีพื้นหลัง (บ่งบอกถึงการเลือก) และขอบ

แพลตฟอร์ม API

ใช้คอมโพสิชัน IconButton เพื่อติดตั้งใช้งานปุ่มไอคอนมาตรฐาน หากต้องการสร้างสไตล์ภาพที่แตกต่างกัน เช่น รูปภาพที่เติมเต็ม รูปภาพที่เติมโทนสี หรือรูปภาพที่วาดเส้นขอบ ให้ใช้ FilledIconButton, FilledTonalIconButton และ OutlinedIconButton ตามลำดับ

พารามิเตอร์หลักสําหรับ IconButton มีดังนี้

  • onClick: ฟังก์ชัน LAMBDA ที่ทำงานเมื่อผู้ใช้แตะปุ่มไอคอน
  • enabled: บูลีนที่ควบคุมสถานะเปิดใช้ของปุ่ม เมื่อ false ปุ่มจะไม่ตอบสนองต่ออินพุตของผู้ใช้
  • content: เนื้อหาแบบคอมโพสิเบิลภายในปุ่ม ซึ่งปกติจะเป็น Icon

ตัวอย่างพื้นฐาน: ปุ่มไอคอนเปิด/ปิด

ตัวอย่างนี้แสดงวิธีใช้ปุ่มไอคอนเปิด/ปิด ไอคอนปุ่มเปิด/ปิดจะเปลี่ยนลักษณะที่ปรากฏโดยขึ้นอยู่กับว่ามีการเลือกหรือไม่เลือก

@Preview
@Composable
fun ToggleIconButtonExample() {
    // isToggled initial value should be read from a view model or persistent storage.
    var isToggled by rememberSaveable { mutableStateOf(false) }

    IconButton(
        onClick = { isToggled = !isToggled }
    ) {
        Icon(
            painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite),
            contentDescription = if (isToggled) "Selected icon button" else "Unselected icon button."
        )
    }
}

ประเด็นสำคัญเกี่ยวกับรหัส

  • Composable ToggleIconButtonExample จะกำหนด IconButton แบบเปิด/ปิดได้
    • mutableStateOf(false) สร้างออบเจ็กต์ MutableState ที่มีค่าบูลีน โดยค่าเริ่มต้นคือ false ซึ่งทําให้ isToggled เป็นผู้ถือสถานะ ซึ่งหมายความว่า Compose จะเขียน UI ใหม่ทุกครั้งที่ค่ามีการเปลี่ยนแปลง
    • rememberSaveable ช่วยให้สถานะ isToggled คงอยู่แม้มีการเปลี่ยนแปลงการกำหนดค่า เช่น การหมุนหน้าจอ
  • onClick lambda ของ IconButton จะกำหนดลักษณะการทำงานของปุ่มเมื่อคลิก โดยสลับสถานะระหว่าง true กับ false
  • พารามิเตอร์ painter ของคอมโพสิเบิล Icon จะโหลด painterResource อื่นแบบมีเงื่อนไขตามสถานะ isToggled ซึ่งจะเปลี่ยนลักษณะที่ปรากฏของไอคอน
    • หาก isToggled เป็น true ระบบจะโหลดรูปหัวใจที่เต็มไปด้วยหัวใจ
    • หาก isToggled เป็น false ระบบจะโหลดรูปหัวใจที่วาดได้ซึ่งมีการร่างเส้นขอบ
  • contentDescription ของ Icon จะอัปเดตตามisToggled สถานะด้วยเพื่อให้ข้อมูลการช่วยเหลือพิเศษที่เหมาะสม

ผลลัพธ์

รูปภาพต่อไปนี้แสดงปุ่มไอคอนเปิด/ปิดจากข้อมูลโค้ดก่อนหน้าในสถานะที่ไม่ได้เลือก

ปุ่มไอคอนเปิด/ปิดรายการโปรด (หัวใจ) ในสถานะไม่ได้เลือก (ไม่เติม)
รูปที่ 2 ปุ่มไอคอนเปิด/ปิด "รายการโปรด" อยู่ในสถานะไม่ได้เลือก

ตัวอย่างขั้นสูง: การดำเนินการซ้ำในการกด

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

@Composable
fun MomentaryIconButton(
    unselectedImage: Int,
    selectedImage: Int,
    contentDescription: String,
    modifier: Modifier = Modifier,
    stepDelay: Long = 100L, // Minimum value is 1L milliseconds.
    onClick: () -> Unit
) {
    val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()
    val pressedListener by rememberUpdatedState(onClick)

    LaunchedEffect(isPressed) {
        while (isPressed) {
            delay(stepDelay.coerceIn(1L, Long.MAX_VALUE))
            pressedListener()
        }
    }

    IconButton(
        modifier = modifier,
        onClick = onClick,
        interactionSource = interactionSource
    ) {
        Icon(
            painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage),
            contentDescription = contentDescription,
        )
    }
}

ประเด็นสำคัญเกี่ยวกับรหัส

  • MomentaryIconButton ใช้ unselectedImage: Int ซึ่งเป็นรหัสแหล่งข้อมูลที่วาดได้สำหรับไอคอนเมื่อไม่ได้กดปุ่ม และ selectedImage: Int ซึ่งเป็นรหัสแหล่งข้อมูลที่วาดได้สำหรับไอคอนเมื่อกดปุ่ม
  • โดยใช้ interactionSource เพื่อติดตามการโต้ตอบ "กด" จากผู้ใช้โดยเฉพาะ
  • isPressed เป็นจริงเมื่อมีการกดปุ่มอยู่ และจะเป็นเท็จในกรณีอื่น เมื่อ isPressed เป็น true LaunchedEffect จะเข้าสู่ลูป
    • ภายในลูปนี้จะใช้ delay (ที่มี stepDelay) เพื่อสร้างการหยุดชั่วคราวระหว่างการดำเนินการที่ทริกเกอร์ coerceIn ตรวจสอบว่าความล่าช้าอย่างน้อย 1 มิลลิวินาทีเพื่อป้องกันการวนซ้ำที่ไม่มีสิ้นสุด
    • ระบบจะเรียกใช้ pressedListener หลังจากการเลื่อนเวลาแต่ละครั้งภายในลูป ซึ่งจะทำให้การดำเนินการซ้ำ
  • pressedListener ใช้ rememberUpdatedState เพื่อให้แน่ใจว่า onClick lambda (การดำเนินการที่จะทำ) เป็นข้อมูลล่าสุดจากคอมโพสิชันล่าสุดเสมอ
  • Icon จะเปลี่ยนรูปภาพที่แสดงโดยขึ้นอยู่กับว่าขณะนี้มีการกดปุ่มหรือไม่
    • หาก isPressed เป็นจริง selectedImage จะแสดง
    • มิฉะนั้น ระบบจะแสดง unselectedImage

ต่อไป ให้ใช้ MomentaryIconButton นี้ในตัวอย่าง ข้อมูลโค้ดต่อไปนี้สาธิตปุ่มไอคอน 2 ปุ่มที่ควบคุมตัวนับ

@Preview()
@Composable
fun MomentaryIconButtonExample() {
    var pressedCount by remember { mutableIntStateOf(0) }

    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically
    ) {
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_rewind,
            selectedImage = R.drawable.fast_rewind_filled,
            stepDelay = 100L,
            onClick = { pressedCount -= 1 },
            contentDescription = "Decrease count button"
        )
        Spacer(modifier = Modifier)
        Text("advanced by $pressedCount frames")
        Spacer(modifier = Modifier)
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_forward,
            selectedImage = R.drawable.fast_forward_filled,
            contentDescription = "Increase count button",
            stepDelay = 100L,
            onClick = { pressedCount += 1 }
        )
    }
}

ประเด็นสำคัญเกี่ยวกับรหัส

  • คอมโพสิเบิล MomentaryIconButtonExample จะแสดง Row ที่มี 2 อินสแตนซ์ MomentaryIconButton และคอมโพสิเบิล Text เพื่อสร้าง UI สําหรับการเพิ่มขึ้นและลดลงของตัวนับ
  • โดยจะเก็บpressedCountตัวแปรสถานะที่เปลี่ยนแปลงได้โดยใช้ remember และ mutableIntStateOf ซึ่งเริ่มต้นที่ 0 เมื่อ pressedCount เปลี่ยนแปลง Composable ทั้งหมดที่สังเกต pressedCount (เช่น Composable Text) จะคอมโพสิทใหม่เพื่อให้สอดคล้องกับค่าใหม่
  • MomentaryIconButton แรกจะลดลง pressedCount เมื่อคลิกหรือกดค้างไว้
  • MomentaryIconButton ตัวที่ 2 จะเพิ่มขึ้น pressedCount เมื่อมีการคลิกหรือกดค้างไว้
  • ปุ่มทั้ง 2 ปุ่มใช้ stepDelay 100 มิลลิวินาที ซึ่งหมายความว่าการกระทํา onClick จะทําซ้ำทุกๆ 100 มิลลิวินาทีขณะที่กดปุ่มค้างไว้

ผลลัพธ์

วิดีโอต่อไปนี้แสดง UI ที่มีปุ่มไอคอนและตัวนับ

รูปที่ 3 UI ตัวนับที่มีปุ่มไอคอน 2 ปุ่ม (บวกและลบ) ที่เพิ่มและลดตัวนับ

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