ท่าทางสัมผัสมือเดียวด้วยฟีเจอร์ช่วยเขียน


ตั้งแต่ Wear OS 7 (API ระดับ 37) เป็นต้นไป เฟรมเวิร์กท่าทางสัมผัสด้วยมือเดียวพร้อมกับ API ที่เป็นส่วนหนึ่งของ Compose สำหรับ Wear OS จะช่วยให้ผู้ใช้โต้ตอบกับแอปของคุณได้โดยไม่ต้องสัมผัส

แม้ว่าในตอนแรกจะรองรับในอุปกรณ์ Pixel Watch (Pixel Watch 3 ขึ้นไป) แต่เฟรมเวิร์กนี้พร้อมให้บริการแก่ OEM ทุกราย การนำ API นี้ไปใช้จะช่วยให้การรองรับท่าทางสัมผัสของแอปปรับขนาดโดยอัตโนมัติตามระบบนิเวศเมื่อมีการขยายการรองรับฮาร์ดแวร์

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

ท่าทางสัมผัสและการดำเนินการที่รองรับ

เฟรมเวิร์กท่าทางสัมผัสของ Wear OS รองรับท่าทางสัมผัส 2 ประเภท ได้แก่

  • การดำเนินการหลัก (บีบนิ้วสองครั้ง): แมปกับการดำเนินการหลักบนหน้าจอ เช่น การรับสายหรือการสลับการเล่นสื่อ
  • การดำเนินการยกเลิก (หมุนข้อมือ): แมปกับการไปยังส่วนต่างๆ ก่อนหน้า การยกเลิกกล่องโต้ตอบ หรือการยกเลิกพรอมต์

กำหนดค่าท่าทางสัมผัสใน Compose

แม้ว่า API ท่าทางสัมผัสด้วยมือเดียวจะช่วยปรับปรุง UI ได้ แต่คุณต้องทราบว่าฮาร์ดแวร์และ OEM บางรายไม่รองรับท่าทางสัมผัสเหล่านี้ หาก API ตรวจพบว่าแอปของคุณทำงานบนอุปกรณ์ที่ไม่รองรับเหล่านี้ ไลบรารีจะดำเนินการแบบไม่มีผลโดยอัตโนมัติโดยไม่ส่งผลต่อการโต้ตอบแบบสัมผัสมาตรฐาน

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

ฟังก์ชัน rememberOneHandedGestureConfiguration จะติดตามประวัติการโต้ตอบของผู้ใช้ในการคอมโพสใหม่โดยไม่เปิดเผยสถานะของแอปพลิเคชัน เมื่อแอปสร้างการกำหนดค่าแล้ว แอปควรส่งการกำหนดค่าไปยัง Modifier.oneHandedGesture ในคอมโพสที่โต้ตอบได้

ไลบรารีมีเมธอด OneHandedGestureClickIndicator เพื่อช่วยให้ผู้ใช้ค้นพบท่าทางสัมผัสที่พร้อมใช้งาน เมธอดนี้ทำหน้าที่เป็น Wrapper ที่แทนที่เนื้อหาพื้นฐานเพื่อระบุให้ผู้ใช้ทราบว่ามีการดำเนินการด้วยท่าทางสัมผัส

คอมโพเนนต์แบบโต้ตอบ

หากต้องการเปิดใช้ท่าทางสัมผัสในตัวควบคุมแบบโต้ตอบ เช่น ปุ่ม ให้สร้างการกำหนดค่าที่ระบุ OneHandedGestureAction.Primary และใช้ตัวปรับแต่ง oneHandedGesture ส่ง MutableInteractionSource เดียวกันไปยังทั้งตัวควบคุมและตัวปรับแต่งเพื่อให้เหตุการณ์ท่าทางสัมผัสส่งสัญญาณตอบสนองแบบภาพไปยังตัวควบคุม

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

var isPlaying by remember { mutableStateOf(false) }
val onClick = { isPlaying = !isPlaying }

val gestureConfig = rememberOneHandedGestureConfiguration(
    action = OneHandedGestureAction.Primary
)
val indicatorState = remember { OneHandedGestureClickIndicatorState() }
val coroutineScope = rememberCoroutineScope()
val interactionSource = remember { MutableInteractionSource() }

Button(
    onClick = onClick,
    interactionSource = interactionSource,
    modifier = Modifier
        .fillMaxWidth()
        .oneHandedGesture(
            gestureConfiguration = gestureConfig,
            interactionSource = interactionSource,
            onGestureLabel = if (isPlaying) "pause" else "play",
            onGestureAvailable = { coroutineScope.launch { indicatorState.showIndicator() } },
            onGesture = onClick
        )
) {
    OneHandedGestureClickIndicator(
        gestureConfiguration = gestureConfig,
        state = indicatorState
    ) {
        Text(if (isPlaying) "Pause" else "Play", modifier = Modifier.fillMaxWidth())
    }
}

คอนเทนเนอร์แบบเลื่อนได้

สำหรับหน้าจอหรือรายการแบบเลื่อนได้ ให้สร้างการกำหนดค่าที่ระบุ OneHandedGestureAction.Primary และใช้ตัวปรับแต่ง oneHandedGesture กับคอนเทนเนอร์ โดยเรียกใช้ตัวช่วยเลื่อน เช่น scrollDown

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

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

val scrollState = rememberTransformingLazyColumnState()
val gestureConfig = rememberOneHandedGestureConfiguration(
    action = OneHandedGestureAction.Primary,
    priority = OneHandedGesturePriority.Scrollable
)
val indicatorState = remember(gestureConfig) { OneHandedGestureScrollIndicatorState() }
val coroutineScope = rememberCoroutineScope()

ScreenScaffold(
    scrollState = scrollState,
    scrollIndicator = {
        OneHandedGestureScrollIndicator(
            gestureConfiguration = gestureConfig,
            indicatorState = indicatorState,
            scrollState = scrollState,
            modifier = Modifier.align(Alignment.CenterEnd)
        )
    }
) { contentPadding ->
    TransformingLazyColumn(
        state = scrollState,
        contentPadding = contentPadding,
        modifier = Modifier
            .fillMaxSize()
            .oneHandedGesture(
                gestureConfiguration = gestureConfig,
                onGestureLabel = "scroll",
                onGestureAvailable = {
                    coroutineScope.launch { indicatorState.showIndicator() }
                },
                onGesture = { OneHandedGestureDefaults.scrollDown(scrollState) }
            )
    ) {
        items(10) { index ->
            Text("Item $index", modifier = Modifier.padding(8.dp))
        }
    }
}

รวมท่าทางสัมผัสหลายรายการ

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

  • OneHandedGesturePriority.Clickable (สูงสุด): กำหนดให้กับตัวควบคุมแบบโต้ตอบ เช่น ตัวควบคุมที่มีประเภท Button หรือ Card เพื่อให้ตัวควบคุมจับท่าทางสัมผัสเมื่อมองเห็นบนหน้าจอ
  • OneHandedGesturePriority.Scrollable (ปานกลาง): กำหนดให้กับคอนเทนเนอร์แบบเลื่อนได้หรือแบบแบ่งหน้าเพื่อให้คอนเทนเนอร์ยอมให้องค์ประกอบย่อยที่คลิกได้ แต่จะเลื่อนเมื่อไม่มีตัวควบคุมที่คลิกได้ปรากฏขึ้น
  • OneHandedGesturePriority.Unspecified (ต่ำสุด): ลำดับความสำคัญที่ไม่ได้กำหนด ซึ่งเป็นค่าเริ่มต้นสำหรับท่าทางสัมผัสที่ไม่ได้ตั้งค่า priority

การตั้งค่า priority = OneHandedGesturePriority.Clickable อย่างชัดเจนในปุ่มด้านในและ priority = OneHandedGesturePriority.Scrollable ในรายการระดับบนจะช่วยให้ระบบแสดงลักษณะการทำงานตามลำดับความสำคัญของท่าทางสัมผัสนี้ได้ เมื่อผู้ใช้ทริกเกอร์การดำเนินการหลักด้วยท่าทางสัมผัสด้วยมือเดียว ระบบจะเลื่อนรายการลงก่อนจนกว่าปุ่มจะปรากฏขึ้น จากนั้นระบบจะจับการดำเนินการคลิกของปุ่ม

ทดสอบและแก้ไขข้อบกพร่องของท่าทางสัมผัสด้วย ADB

คุณสามารถทดสอบท่าทางสัมผัสด้วยมือเดียวในอุปกรณ์จริงหรือโปรแกรมจำลองโดยไม่ต้องขยับข้อมือจริงได้โดยใช้ Android Debug Bridge (adb) และบริการของระบบ IWearGestureService

เปิดใช้การจำลองท่าทางสัมผัส

  1. ตรวจสอบว่าอุปกรณ์ Wear OS ของคุณใช้ Wear OS 7 (ระดับ API 37) ขึ้นไป
  2. หากทดสอบในอุปกรณ์จริงที่ไม่ได้สวมไว้ที่ข้อมือหรือไม่ได้เสียบปลั๊กที่ชาร์จ ให้ลบล้างสถานะเซ็นเซอร์นอกร่างกายเพื่อให้อุปกรณ์ยังคงทำงานอยู่
adb shell cmd sensorservice set-off-body-state 0

ทริกเกอร์เหตุการณ์ท่าทางสัมผัสโดยใช้ ADB

หากต้องการจำลองท่าทางสัมผัสบีบ 2 นิ้ว (ซึ่งเป็นการดำเนินการ Primary ใน Pixel Watch) ให้เรียกใช้คำสั่ง ADB Shell ต่อไปนี้

adb shell cmd IWearGestureService gesture 1

หากต้องการจำลองท่าทางสัมผัสหมุนข้อมือ (ซึ่งเป็นการดำเนินการ Dismiss ใน Pixel Watch) ให้เรียกใช้คำสั่ง ADB Shell ต่อไปนี้

adb shell cmd IWearGestureService gesture 2

รีเซ็ตการติดตามคำแนะนำท่าทางสัมผัส

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

adb shell cmd IWearGestureService hint clear <your_package_name>

วิธีรีเซ็ตสถานะเซ็นเซอร์นอกร่างกายเมื่อทดสอบเสร็จแล้ว

adb shell cmd sensorservice reset-off-body-state

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

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