รากฐาน UX สําหรับเฟรมเวิร์กการสัมผัส

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

หลักการ UX

รูปที่ 1 หลักการปัจจุบัน

ตารางต่อไปนี้แสดง API การสั่นทั้งหมดที่พร้อมใช้งาน

API วิธีการและค่าคงที่ ปีที่เพิ่ม
android.view.HapticFeedbackConstants
  • CONTEXT_CLICK
  • CLOCK_TICK
  • VIRTUAL_KEY
  • KEYBOARD_TAP
  • LONG_PRESS
ก่อนปี 2016
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY_RELEASE
2017 (Android 8)
  • CONFIRM
  • REJECT
  • GESTURE_START
  • GESTURE_END
2020 (Android 11)
android.View
  • performHapticFeedback()
ก่อนปี 2016
android.os.Vibrator
  • vibrate()
  • hasVibrator()
ก่อนปี 2016
  • hasAmplitudeControl()
2017 (Android 8)
  • areAllEffectsSupported()
  • areAllPrimitivesSupported()
  • areEffectsSupported()
  • arePrimitivesSupported()
2020 (Android 11)
android.os.VibrationEffect
  • createOneShot()
  • createWaveform()
2017 (Android 8)
  • EFFECT_TICK
  • EFFECT_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_DOUBLE_CLICK
  • createPredefined()
2019 (Android 10)
android.os.VibrationEffect.Composition
  • PRIMITIVE_TICK
  • PRIMITIVE_CLICK
  • addPrimitive()
  • compose()
2020 (Android 11)
android.media.AudioAttributes.Builder
  • setHapticChannelsMuted()
2019 (Android 10)

การสั่นแบบมีเสียงหึ่ง

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

ล้างการโต้ตอบการสัมผัส

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

Android มุ่งมั่นที่จะมอบการสั่นที่ชัดเจนพร้อมความรู้สึกที่หนักแน่นแต่คมชัด แทนที่จะเป็นความรู้สึกที่สั่นหรือนุ่มนวล

ค่าคงที่แบบสัมผัสที่กำหนดไว้ล่วงหน้าซึ่งสร้างขึ้นเพื่อรองรับการตอบสนองแบบสัมผัสที่ชัดเจนประกอบด้วยองค์ประกอบต่อไปนี้

ใน HapticFeedbackConstants:

  • CLOCK_TICK
  • CONFIRM
  • CONTEXT_CLICK
  • GESTURE_END
  • GESTURE_START
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • KEYBOARD_TAP
  • LONG_PRESS
  • REJECT
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY
  • VIRTUAL_KEY_RELEASE

ใน VibrationEffect:

  • EFFECT_CLICK
  • EFFECT_DOUBLE_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_TICK

การสร้างความรู้ร่วมกันระหว่างผู้ผลิตอุปกรณ์และนักพัฒนาแอปเป็นกุญแจสำคัญในการ ยกระดับคุณภาพโดยรวมของการตอบสนองแบบสัมผัสในระบบนิเวศของ Android ใช้รายการตรวจสอบพื้นฐาน การประเมินฮาร์ดแวร์ และ CDD เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับการติดตั้งใช้งานการสัมผัส

กดค้างแล้วปล่อย

รูปที่ 2 การกดและปล่อย

การโต้ตอบการสัมผัสที่สมบูรณ์

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

การโต้ตอบการสัมผัสที่สมบูรณ์

รูปที่ 3 การโต้ตอบการสัมผัสที่สมจริงพร้อมพื้นผิวที่ลื่น

การลากและการปัด

รูปที่ 4 การลากและการปัด

กรณีการใช้งานที่ 1: พื้นผิวเลื่อน

หากมีการทำซ้ำเอฟเฟกต์การสัมผัสขณะที่นิ้วเลื่อนเหนือพื้นผิวสัมผัส (เช่น การลาก การปัด การสำรวจพื้นผิวด้วยพื้นผิวสัมผัสเสมือนจริง) เอฟเฟกต์การสัมผัสที่ทำซ้ำควรคมชัดและละเอียด

หากเอฟเฟกต์แต่ละรายการมีเสียงก้องมากกว่าเสียงคมชัด ระบบอาจลบช่วงเวลาระหว่าง การทำซ้ำออก ผลลัพธ์คือเสียงหึ่งยาว 1 ครั้ง แทนที่จะเป็นสัญญาณแยกกันหลายครั้ง

หากแอมพลิจูดไม่ละเอียดพอ พลังงานสัมผัสที่รับรู้จะเพิ่มขึ้น ผ่านการทำซ้ำ ส่งผลให้เกิดการสั่นที่แรงมากเมื่อสิ้นสุด การทำซ้ำ

ใช้พื้นผิวสัมผัสบนพื้นผิวสำหรับท่าทางสัมผัสแบบปัดและลาก

ใช้ CLOCK_TICK และ TEXT_HANDLE_MOVE ใน HapticFeedbackConstants ค่าคงที่เหล่านี้กำหนดลักษณะของการทำซ้ำและแอมพลิจูดไว้ล่วงหน้า

สร้างเอฟเฟกต์ของคุณเอง

หากต้องการสร้างเอฟเฟกต์ของคุณเอง ให้ออกแบบโดยการต่อลำดับของ PRIMITIVE_CLICK และ PRIMITIVE_TICK ใน VibrationEffect.Composition คุณสามารถปรับลักษณะของการทำซ้ำและสเกลแอมพลิจูด โดยใช้ addPrimitive(int primitiveID, float scale, int delay) การรองรับจะขึ้นอยู่กับความสามารถของ CAP_COMPOSE_EFFECTS ในอินเทอร์เฟซ HAL ของ Vibrator

กรณีการใช้งานที่ 2: การสั่นยาวพร้อมเอฟเฟกต์ Ease-in

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

ใช้เอฟเฟกต์ Ease In

  1. ตรวจสอบความสามารถของฮาร์ดแวร์ในการควบคุมแอมพลิจูดด้วย android.os.Vibrator.hasAmplitudeControl()

    • ผลลัพธ์ต้องเป็น true เพื่อสร้างเอฟเฟกต์ Ease In ที่มี แอมพลิจูดแตกต่างกัน
  2. ใช้ VibrationEffectcreateWaveform(timings[], amplitudes[], int repeat)

  3. ปรับชุด timings[] และ amplitudes[] เพื่อสร้างเส้นโค้งการชะลอความเร็วตอนต้น ดังที่แสดงในรูปที่ 5

การสั่นยาว

รูปที่ 5 เส้นโค้งการสั่นยาวแบบค่อยๆ เพิ่มความเร็ว

กรณีการใช้งานที่ 3: การโต้ตอบการสัมผัสที่เชื่อมต่อกับเสียง

การสั่นที่เชื่อมโยงกับเสียงคือรูปแบบการสั่นที่เชื่อมโยงกับจังหวะของเสียง เพื่อดึงดูดความสนใจของผู้ใช้

การสั่นแบบรู้สึกได้ที่เชื่อมต่อกับเสียง: ประโยชน์

หากต้องการใช้การสัมผัสที่เชื่อมต่อกับเสียง ให้รวมการสัมผัสที่ชัดเจนเข้ากับการสั่นสะเทือนที่ยาวนาน การสั่นที่หนักแน่นแต่สั้นจากฟีเจอร์สัมผัสที่ชัดเจนจะสร้างรูปแบบจังหวะที่แยกกัน เมื่อใช้ร่วมกับระดับการกระตุ้นที่สูงซึ่งการสั่นสะเทือนยาวนานมอบให้ การสั่นสะเทือนนี้จะดึงดูดความสนใจของผู้ใช้ได้เป็นอย่างดี

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

คู่รัก

รูปที่ 6 ตัวอย่างการสัมผัสคู่เสียง

การโต้ตอบการสัมผัสที่เชื่อมต่อกับเสียง: เคล็ดลับในการติดตั้งใช้งาน

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

  • ใช้คลาส MediaPlayer หรือ SoundPool

    • เนื้อหาในรูปแบบ OGG ที่มีคีย์ข้อมูลเมตาพิเศษ (ANDROID_HAPTIC ตามด้วยจำนวนช่องสัมผัส) จะระบุ การมีอยู่ของข้อมูลสัมผัสและการเล่นด้วย MediaPlayer และ SoundPool
  • ระบุการรองรับการตอบสนองแบบสัมผัสและการเล่นเสียงใน audio_policy_configuration.xml

    • ใช้โปรไฟล์เอาต์พุตที่มีช่องการโต้ตอบการสัมผัส AUDIO_CHANNEL_OUT_HAPTIC_A|B
    • สำหรับสตรีมเอาต์พุตที่มีแชแนลสัมผัส โปรดทราบว่าแชแนลสัมผัส จะแสดงเป็นแชแนลพิเศษในข้อมูล

    ตัวอย่าง

    หากมาสก์ช่องสำหรับสตรีมเอาต์พุตมีลักษณะดังนี้

    AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A

    จากนั้นตัวอย่างทั้งหมดควรมีลักษณะดังนี้

    AUDIO_LEFT_CHANNEL,AUDIO_RIGHT_CHANNEL,HAPTIC_CHANNEL_A

  • เปลี่ยน AudioAttributes.Builder( ).setHapticChannelsMuted(boolean muted) เป็น false เพื่อเล่นช่องการสั่น

    • โดยค่าเริ่มต้น ระบบจะปิดเสียงแชแนลการสั่น (true)
    • กรณีการใช้งาน ได้แก่ เสียงเรียกเข้าและเสียง UI ที่มีการตอบสนองแบบสัมผัสและฟีดแบ็กแบบซิงโครนัส
  • HAL ของเครื่องสั่นต้องรองรับการควบคุมภายนอก

การโต้ตอบการสัมผัสที่เชื่อมต่อกับเสียง

รูปที่ 7 การใช้แฮปติกที่เชื่อมต่อกับเสียง

การโต้ตอบการสัมผัสที่เชื่อมต่อกับเสียง: HapticGenerator

HapticGenerator คือเอฟเฟกต์เสียงที่เปิดตัวใน Android 12 ซึ่ง สามารถสร้างข้อมูลการสั่นจากช่องเสียงและเล่นแบบเรียลไทม์เป็นการสั่นที่เชื่อมโยงกับเสียง ระบบจะใช้เอฟเฟกต์กับ AudioTrack ตามที่แสดงในรูปที่ 8 ดังนี้

สถาปัตยกรรม Haptic Generator

รูปที่ 8 สถาปัตยกรรม Haptic Generator

ภาพการแสดงสถาปัตยกรรมนี้แสดงให้เห็นว่ามีการใช้ Haptic Generator กับ สตรีมเสียงของผู้ใช้ที่เข้ามาที่ใดก่อนที่จะส่งไปยัง Audio HAL ระบบจะใช้เครื่องกำเนิด หลังจากที่ AudioMixer แยกข้อมูลเสียงและข้อมูลการสัมผัส และก่อนที่จะใช้เอฟเฟกต์เสียงอื่นๆ และเอาต์พุตของเครื่องกำเนิดจะลบล้างข้อมูลการสัมผัสก่อนหน้าในสตรีม

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

  • ความถี่เรโซแนนซ์สำหรับตัวกรองแถบความถี่ผ่าน

    ความถี่เรโซแนนซ์ของไวเบรเตอร์คือความถี่ที่แอคทูเอเตอร์แบบสัมผัส มีเอาต์พุตสูงสุด พารามิเตอร์นี้จะปรับตัวต้านเรโซเนเตอร์เพื่อทำให้ฟังก์ชันการโอนการตอบสนองแบนราบบางส่วน เพื่อให้ได้แบนด์วิดท์ที่กว้างขึ้น เฟรมเวิร์ก Android จะลิงก์ค่านี้กับเอาต์พุตของเมธอด HAL ของ Vibrator IVibrator.getResonantFrequency โดยอัตโนมัติ

    ค่าเริ่มต้นของพารามิเตอร์นี้คือ 150 Hz คุณแก้ไขค่านี้ได้ในโค้ด

  • กำลังการปรับให้เป็นมาตรฐานสำหรับซองจดหมายช้า

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

  • ค่า Q สำหรับตัวกรองแถบหยุด

    ปัจจัยคุณภาพของเครื่องสั่น (ปัจจัย Q) กำหนดโดยพารามิเตอร์ 2 รายการ ได้แก่

    • Zero Q คือปัจจัยด้านคุณภาพของศูนย์ในตัวกรองแถบหยุดที่ ยกเลิกเรโซแนนซ์บางส่วน

    • Pole Q ซึ่งเป็นค่าคุณภาพของขั้วในตัวกรองแถบหยุด

    อัตราส่วนของค่าทั้ง 2 นี้จะจำกัดการระงับเรโซแนนซ์ เพื่อเพิ่มความถี่ต่ำและขยายการตอบสนองของอัลกอริทึม ตัวอย่างเช่น ค่าเริ่มต้นของ 8 สำหรับ Q ที่เป็น 0 และ 4 สำหรับ Q ที่เป็นเสาจะทำให้เกิด อัตราส่วน 2 ซึ่งจำกัดการระงับเรโซแนนซ์ด้วยปัจจัย 2 (6 dB) เฟรมเวิร์ก Android จะลิงก์ค่าทั้ง 2 ค่ากับเอาต์พุตของเมธอด HAL ของ Vibrator IVibrator.getQFactor

    หากค่าเริ่มต้นไม่ได้คำนึงถึงการลดความแรงของมอเตอร์ ในอุปกรณ์ เราขอแนะนำให้แก้ไขทั้ง 2 ค่าพร้อมกัน และ เพิ่มหรือลดทั้ง 2 ค่า อัตราส่วนของ Q ที่เป็น 0 ต่อ Q ที่เป็นขั้ว ควรมากกว่า 1 คุณแก้ไขได้ในโค้ด

  • ความถี่คัตออฟสำหรับการบิดเบือน

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

  • เกนอินพุตและเกณฑ์ลูกบาศก์สำหรับการบิดเบือน

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

    • ค่าเริ่มต้นสำหรับปัจจัยการเพิ่มอินพุตคือ 0.3
    • ค่าเริ่มต้นสำหรับเกณฑ์ลูกบาศก์คือ 0.1

    เราขอแนะนําให้แก้ไขทั้ง 2 ค่าพร้อมกัน โดยจะอยู่ในโค้ด

    ดูข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชันที่ใช้โดยตัวกรองนี้ได้ที่การติดตั้งใช้งานในโค้ด

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

  • เอาต์พุตเกนสำหรับการบิดเบือน

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

    หากการสั่นเบาเกินไป ให้เพิ่มค่า หากได้ยินเสียง ฮาร์ดแวร์แอคทูเอเตอร์สั่น ให้ลดค่า