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


ใน 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ใน Composable แบบอินเทอร์แอกทีฟ

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

คอมโพเนนต์แบบอินเทอร์แอกทีฟ

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

หากต้องการเปิดใช้ตัวบ่งท่าทางสัมผัส ให้สร้างและจดจำอินสแตนซ์ของ OneHandedGestureClickIndicatorState จากนั้นเรียกใช้ showIndicator ภายใน Callback ของ 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

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

ก่อนจำลองท่าทางสัมผัสโดยใช้ ADB ให้กำหนดค่าการตั้งค่าอุปกรณ์และการลบล้างข้อจำกัด ดังนี้

  1. ตรวจสอบว่าอุปกรณ์ Wear OS ของคุณใช้ Wear OS 7 (ระดับ API 37) ขึ้นไป

    adb shell getprop ro.build.version.sdk
    
  2. หากคุณกำลังทดสอบบนอุปกรณ์จริงที่ไม่ได้อยู่บนข้อมือหรือวางอยู่บนที่ชาร์จ ให้ลบล้างข้อจำกัดนอกร่างกายเพื่อให้เฟรมเวิร์กท่าทางสัมผัสยังคงใช้งานได้ โดยทำดังนี้

    adb shell cmd IWearGestureService override-constraints offbody-state
    

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

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

adb shell cmd IWearGestureService gesture DoublePinch

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

adb shell cmd IWearGestureService gesture WristTurn

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

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

  • ในบิลด์หรือโปรแกรมจำลอง userdebug

    adb shell cmd IWearGestureService hint clear <your_package_name>
    
  • ในบิลด์สำหรับค้าปลีก (user)

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

    adb shell pm clear <your_package_name>
    

กู้คืนข้อจำกัดเริ่มต้น

วิธีรีเซ็ตการลบล้างข้อจํากัดการแก้ไขข้อบกพร่องทั้งหมดเมื่อทดสอบเสร็จแล้ว

adb shell cmd IWearGestureService override-constraints reset

แก้ปัญหาการแทรกท่าทางสัมผัส

หากแอปไม่ได้รับการแตะที่จำลอง ให้ทำดังนี้

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

    adb shell input keyevent KEYCODE_WAKEUP
    
  2. ตรวจสอบว่าแอปของคุณลงทะเบียนเป็นผู้รับการแจ้งเตือนท่าทางสัมผัสที่ใช้งานอยู่และ ปัจจุบันมีโฟกัสหน้าต่างหรือไม่

    adb shell cmd IWearGestureService get-active-gestures -readable
    

    เมื่อหน้าจอท่าทางสัมผัสของแอปอยู่เบื้องหน้าและหน้าจอเปิดอยู่ คำสั่งนี้จะแสดงผล [DoublePinch] หรือ [DoublePinch, WristTurn] หากระบบแสดงรายการว่าง ([]) ให้ตรวจสอบว่าหน้าต่างมีโฟกัสหรือไม่ หรือข้อจำกัดนอกร่างกายบล็อกการเปิดใช้งานหรือไม่

  3. ตรวจสอบสถานะบริการท่าทางสัมผัสภายในและโทเค็นของผู้ติดตามที่ใช้งานอยู่

    adb shell dumpsys IWearGestureService
    

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

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