เครื่องมือแก้ไขข้อความที่กำหนดเอง

เครื่องมือแก้ไขข้อความที่กำหนดเองเป็นมุมมองที่ EditText คอมโพเนนต์หรือ วิดเจ็ตข้อความ WebView รายการแต่ แต่ก็รองรับการป้อนข้อความโดยใช้ onCreateInputConnection() Callback ซึ่งเรียกใช้เมื่อโฟกัสที่มุมมองและระบบร้องขอ InputConnection สำหรับมุมมอง

การโทรถึง onCheckIsTextEditor() จากเครื่องมือแก้ไขข้อความที่กำหนดเองควรแสดงผล true

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

Android 14 (API ระดับ 34) ขึ้นไปรองรับการป้อนข้อมูลด้วยสไตลัสใน Android มาตรฐาน คอมโพเนนต์การป้อนข้อความโดยค่าเริ่มต้น (ดูการป้อนข้อมูลสไตลัสในข้อความ ฟิลด์) อย่างไรก็ตาม ช่องป้อนข้อความที่กำหนดเอง (หรือโปรแกรมแก้ไข) ต้องมีการพัฒนาเพิ่มเติม

วิธีสร้างเครื่องมือแก้ไขข้อความที่กำหนดเอง

  1. เปิดใช้การเริ่มเขียนด้วยลายมือ
  2. ประกาศการรองรับการเขียนด้วยลายมือ
  3. รองรับท่าทางสัมผัสการเขียนด้วยลายมือ (เลือก ลบ แทรก และอื่นๆ)
  4. ระบุตำแหน่งเคอร์เซอร์และข้อมูลตำแหน่งอื่นๆ แก่ IME
  5. แสดงไอคอนการเขียนด้วยลายมือโดยใช้สไตลัส

เปิดใช้การเริ่มเขียนด้วยลายมือ

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

การเริ่มต้นการเขียนด้วยลายมืออัตโนมัติ

หากมุมมองแสดงโปรแกรมแก้ไขข้อความเดียวและไม่มีเนื้อหาอื่น มุมมองนั้นสามารถเลือก เข้าสู่จุดเริ่มต้นการเขียนด้วยลายมืออัตโนมัติของระบบการดู โดยการเรียก setAutoHandwritingEnabled(true)

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

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

การเริ่มเขียนด้วยลายมือที่กําหนดเอง

หากมุมมองหนึ่งมีเครื่องมือแก้ไขข้อความหลายรายการหรือเนื้อหานอกเหนือจากข้อความเดียว มุมมองนี้จะต้องใช้ตรรกะการเริ่มต้นการเขียนด้วยลายมือของตัวเองดังนี้

  1. เลือกไม่ใช้การเริ่มต้นการเขียนด้วยลายมืออัตโนมัติของระบบมุมมองโดยการโทร setAutoHandwritingEnabled(false)

  2. ติดตามเครื่องมือแก้ไขข้อความทั้งหมดที่ปรากฏภายในมุมมอง

  3. ตรวจสอบเหตุการณ์การเคลื่อนไหวที่มุมมองใน dispatchTouchEvent()

    • เมื่อการเคลื่อนไหวของสไตลัสเกิดขึ้นภายในขอบเขตการเขียนด้วยลายมือของโปรแกรมแก้ไขข้อความ โฟกัสเครื่องมือแก้ไขข้อความ (หากยังไม่ได้โฟกัส)

    • หากเครื่องมือแก้ไขไม่ได้โฟกัสอยู่ ให้รีสตาร์ท IME ของเครื่องมือแก้ไขด้วย เนื้อหาด้วยการเรียก InputMethodManager#restartInput()

    • เริ่มเซสชันการเขียนด้วยลายมือโดยใช้สไตลัสโดยการเรียกใช้ InputMethodManager#startStylusHandwriting()

หากเครื่องมือแก้ไขข้อความอยู่ในมุมมองที่เลื่อนได้ การเคลื่อนที่ของสไตลัสภายใน ขอบเขตการเขียนด้วยลายมือของเอดิเตอร์ควรถือเป็นการเขียนด้วยลายมือ ไม่ใช่การเลื่อน ใช้ ViewParent#requestDisallowInterceptTouchEvent() เพื่อป้องกันไม่ให้มุมมองระดับบนแบบเลื่อนได้ขัดขวางกิจกรรมการแตะจากข้อความ Editor

รายละเอียด API

  • MotionEvent#getToolType() — ระบุว่า MotionEvent มาจากสไตลัสหรือไม่ ซึ่งในกรณีนี้ ผลลัพธ์คือ TOOL_TYPE_STYLUS หรือ TOOL_TYPE_ERASER

  • InputMethodManager#isStylusHandwritingAvailable() — ระบุว่า IME รองรับการเขียนด้วยลายมือโดยใช้สไตลัสหรือไม่ โทรหาที่นี่ ก่อนการเรียกไปยัง InputMethodManager#startStylusHandwriting() ทุกครั้ง เนื่องจากความพร้อมใช้งานของลายมืออาจมีการเปลี่ยนแปลง

  • InputMethodManager#startStylusHandwriting() — ทำให้ IME เข้าสู่โหมดการเขียนด้วยลายมือ CANNOT TRANSLATE ACTION_CANCEL ระบบจะส่งเหตุการณ์การเคลื่อนไหวไปยังแอปเพื่อยกเลิกท่าทางสัมผัสปัจจุบัน สไตลัส ระบบจะไม่ส่งเหตุการณ์การเคลื่อนไหวไปยังแอปอีกต่อไป

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

    หาก IME เข้าสู่โหมดการเขียนด้วยลายมือไม่ได้ การเรียกใช้เมธอดนี้จะไม่ดำเนินการ

ประกาศการรองรับการเขียนด้วยลายมือ

เมื่อกรอกข้อมูลใน อาร์กิวเมนต์ EditorInfo จาก การโทร View#onCreateInputConnection(EditorInfo) สาย setStylusHandwritingEnabled() เพื่อแจ้งให้ IME ทราบว่าเครื่องมือแก้ไขข้อความรองรับการเขียนด้วยลายมือ ประกาศท่าทางสัมผัสที่รองรับด้วย setSupportedHandwritingGestures() และ setSupportedHandwritingGesturePreviews()

รองรับท่าทางสัมผัสการเขียนด้วยลายมือ

IME สามารถรองรับท่าทางสัมผัสการเขียนด้วยลายมือที่หลากหลาย เช่น การวาดข้อความวงกลมเพื่อเลือก หรือลากเส้นบนข้อความเพื่อลบ

รูปที่ 2 วงเพื่อเลือกข้อความ
รูปที่ 3 วาดลายเส้นเพื่อลบข้อความ

ใช้เครื่องมือแก้ไขที่กำหนดเอง InputConnection#performHandwritingGesture() และ InputConnection#previewHandwritingGesture() เพื่อรองรับการใช้ HandwritingGesture ประเภทต่างๆ เช่น SelectGesture DeleteGesture และ InsertGesture

ประกาศท่าทางสัมผัสการเขียนด้วยลายมือที่รองรับเมื่อกรอกอาร์กิวเมนต์ EditorInfo จาก View#onCreateInputConnection(EditorInfo) (ดูส่วนประกาศลายมือ การสนับสนุนของเรา)

รายละเอียด API

  • InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer) — ใช้ท่าทางสัมผัส อาร์กิวเมนต์ HandwritingGesture ประกอบด้วย ซึ่งสามารถใช้กำหนดตำแหน่งของข้อความที่จะ ทำท่าทางสัมผัส ตัวอย่างเช่น SelectGesture จะระบุ RectF ออบเจ็กต์ที่ ระบุช่วงข้อความที่เลือก และ InsertGesture จะระบุช่วงข้อความ PointF ออบเจ็กต์ที่ ระบุออฟเซ็ตข้อความที่จะแทรกข้อความ

    ใช้Executorและ พารามิเตอร์ IntConsumer เพื่อส่งกลับผลของการดำเนินการ เมื่อทั้งผู้ดำเนินการและ มีการระบุอาร์กิวเมนต์ผู้บริโภค ใช้ตัวดำเนินการเพื่อเรียก IntConsumer#accept() เช่น

    
    executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
    
    
  • HandwritingGesture#getFallbackText() — แสดงข้อความสำรองที่ IME ผูกไว้ที่ตำแหน่งเคอร์เซอร์หากไม่มี ข้อความที่ใช้ได้จะอยู่ใต้บริเวณของท่าทางสัมผัสที่เขียนด้วยลายมือ

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

    ตัวอย่างเช่น หาก IME ตรวจสอบไม่ได้ว่าผู้ใช้ตั้งใจจะวาด เครื่องหมายลูกศรชี้ลง ⋁ เพื่อทำท่าทางสัมผัสการแทรกการเว้นวรรคหรือการเขียนด้วยลายมือ ตัวอักษร "v" IME สามารถส่ง InsertGesture ที่มีข้อความสำรอง "v"

    เอดิเตอร์ควรพยายามทำท่าทางสัมผัสการแทรกการเว้นวรรคก่อน หาก ใช้ท่าทางสัมผัสไม่ได้ (เช่น ไม่มีข้อความในตำแหน่ง ) เครื่องมือแก้ไขควรกลับไปใช้การแทรก "v" ที่เคอร์เซอร์ ตำแหน่ง

  • InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal) — แสดงตัวอย่างท่าทางสัมผัสต่อเนื่อง เช่น เมื่อผู้ใช้เริ่มวาด วงกลมรอบข้อความ ตัวอย่างแบบเรียลไทม์ของสิ่งที่เลือกอาจ แสดงและอัปเดตอย่างต่อเนื่องขณะที่ผู้ใช้วาดต่อ เฉพาะบางรายการ ประเภทของท่าทางสัมผัสสามารถดูตัวอย่างได้ (ดูที่ PreviewableHandwritingGesture)

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

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

ระบุตำแหน่งเคอร์เซอร์และข้อมูลตำแหน่งอื่นๆ

IME สามารถขอตำแหน่งของเคอร์เซอร์และข้อมูลตำแหน่งอื่นๆ ในโหมดการเขียนด้วยลายมือ โดยใช้ InputConnection#requestCursorUpdates() ตัวแก้ไขที่กำหนดเองตอบกลับด้วยการเรียก InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo) ข้อมูลใน CursorAnchorInfo ซึ่งเกี่ยวข้องกับการเขียนด้วยลายมือโดยใช้สไตลัส CursorAnchorInfo.Builder วิธีการ:

  • setInsertionMarkerLocation() — ตั้งค่าตำแหน่งของเคอร์เซอร์ IME ใช้ค่าเพื่อทำให้เคลื่อนไหว เขียนด้วยลายมือไปที่ตำแหน่งเคอร์เซอร์
  • setEditorBoundsInfo() — ตั้งค่าขอบเขตของเครื่องมือแก้ไขและขอบเขตของการเขียนด้วยลายมือ IME ใช้ ข้อมูลนี้เพื่อวางตำแหน่งแถบเครื่องมือการเขียนด้วยลายมือของ IME บนหน้าจอ
  • addVisibleLineBounds() — ตั้งค่าขอบเขตของบรรทัดข้อความที่มองเห็นได้ทั้งหมด (หรือมองเห็นได้บางส่วน) ของ เอดิเตอร์ IME ใช้ขอบเขตของเส้นเพื่อปรับปรุงความแม่นยำในการจดจำ ท่าทางสัมผัสการเขียนด้วยลายมือ
  • setTextAppearanceInfo() — ตั้งค่าลักษณะที่ปรากฏของข้อความด้วยข้อมูลที่ได้จากข้อความ ฟิลด์ป้อนข้อมูล IME จะใช้ข้อมูลดังกล่าวเพื่อจัดรูปแบบหมึกสำหรับลายมือ

แสดงไอคอนการเขียนด้วยลายมือโดยใช้สไตลัส

แสดงไอคอนการเขียนด้วยลายมือของสไตลัสเมื่อสไตลัสวางอยู่เหนือ ขอบเขตการเขียนด้วยลายมือของเครื่องมือแก้ไขข้อความที่กำหนดเองและ IME ที่เลือกรองรับ การเขียนด้วยลายมือโดยใช้สไตลัส (InputMethodManager#isStylusHandwritingAvailable())

ลบล้าง View#onResolvePointerIcon() เพื่อดูไอคอนการเขียนด้วยลายมือโดยใช้สไตลัส ในการลบล้าง เรียก PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING) เพื่อเข้าถึงไอคอนการเขียนด้วยลายมือของสไตลัสของระบบ

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