Trình chỉnh sửa văn bản tuỳ chỉnh

Trình chỉnh sửa văn bản tuỳ chỉnh là những khung hiển thị không được EditText hoặc WebView tiện ích văn bản nhưng Tuy nhiên, hỗ trợ nhập văn bản bằng cách triển khai onCreateInputConnection() được gọi khi một khung hiển thị được lấy làm tâm điểm và hệ thống yêu cầu một InputConnection cho chế độ xem.

Cuộc gọi đến onCheckIsTextEditor() từ trình chỉnh sửa văn bản tuỳ chỉnh sẽ trả về true.

Hỗ trợ chữ viết tay bằng bút cảm ứng trong trình chỉnh sửa văn bản tuỳ chỉnh

Android 14 (API cấp 34) trở lên hỗ trợ phương thức nhập bằng bút cảm ứng trong các phiên bản Android tiêu chuẩn các thành phần nhập văn bản theo mặc định (xem Phương thức nhập bằng bút cảm ứng trong văn bản trường). Tuy nhiên, các trường nhập (hoặc trình chỉnh sửa) văn bản tuỳ chỉnh cần được phát triển thêm.

Để tạo một trình chỉnh sửa văn bản tuỳ chỉnh, hãy làm như sau:

  1. Bật tính năng khởi tạo chữ viết tay
  2. Khai báo tính năng hỗ trợ chữ viết tay
  3. Hỗ trợ cử chỉ viết tay (chọn, xoá, chèn, v.v.)
  4. Cung cấp vị trí con trỏ và dữ liệu vị trí khác cho IME
  5. Hiện biểu tượng di chuột viết tay bằng bút cảm ứng

Bật tính năng khởi tạo chữ viết tay

Nếu khung hiển thị chỉ bao gồm một trình chỉnh sửa văn bản, thì hệ thống khung hiển thị có thể tự động bắt đầu viết tay bằng bút cảm ứng cho chế độ xem. Nếu không, khung hiển thị phải triển khai logic khởi tạo chữ viết tay riêng.

Khởi tạo chữ viết tay tự động

Nếu một khung hiển thị chỉ hiện một trình chỉnh sửa văn bản và không có nội dung nào khác, thì khung hiển thị đó có thể chọn vào việc khởi tạo chữ viết tay tự động của hệ thống chế độ xem bằng cách gọi setAutoHandwritingEnabled(true).

Khi bật tính năng tự động viết tay, chuyển động của bút cảm ứng sẽ bắt đầu ở bất cứ đâu trong chế độ xem ranh giới chữ viết tay sẽ tự động bắt đầu chế độ viết tay. Phương thức nhập trình chỉnh sửa (IME) nhận được sự kiện chuyển động của bút cảm ứng và xác nhận văn bản đã nhận dạng.

Trường nhập dữ liệu có hình chữ nhật xung quanh cho biết giới hạn phát hiện các sự kiện chuyển động của bút cảm ứng.
Hình 1. Chữ viết tay trong giới hạn của trường EditText.

Bắt đầu viết tay tuỳ chỉnh

Nếu một khung hiển thị chứa nhiều trình chỉnh sửa văn bản hoặc nội dung ngoài một văn bản thì khung hiển thị đó phải triển khai logic khởi tạo chữ viết tay riêng như sau:

  1. Chọn không tham gia tính năng tự động khởi tạo chữ viết tay của hệ thống chế độ xem bằng cách gọi setAutoHandwritingEnabled(false).

  2. Theo dõi tất cả trình chỉnh sửa văn bản hiển thị trong chế độ xem.

  3. Theo dõi sự kiện chuyển động mà chế độ xem nhận được trong dispatchTouchEvent().

    • Khi chuyển động của bút cảm ứng xảy ra trong ranh giới chữ viết tay của trình chỉnh sửa văn bản, đặt tiêu điểm vào trình chỉnh sửa văn bản (nếu chưa đặt tiêu điểm).

    • Nếu trình chỉnh sửa chưa được lấy làm tâm điểm, hãy khởi động lại IME của trình chỉnh sửa bằng bằng cách gọi InputMethodManager#restartInput().

    • Bắt đầu phiên viết tay bằng bút cảm ứng bằng cách gọi InputMethodManager#startStylusHandwriting().

Nếu trình chỉnh sửa văn bản ở trong chế độ xem có thể cuộn, thì chuyển động của bút cảm ứng trong ranh giới chữ viết tay của người chỉnh sửa phải được coi là chữ viết tay, chứ không phải cuộn. Sử dụng ViewParent#requestDisallowInterceptTouchEvent() để ngăn chế độ xem đối tượng cấp trên có thể cuộn cản trở các sự kiện chạm trong một văn bản trình chỉnh sửa.

Thông tin chi tiết về API

  • MotionEvent#getToolType() — Cho biết liệu MotionEvent có phải từ bút cảm ứng hay không, trong trường hợp nào giá trị trả về là TOOL_TYPE_STYLUS hoặc TOOL_TYPE_ERASER.

  • InputMethodManager#isStylusHandwritingAvailable() — Cho biết liệu IME có hỗ trợ chữ viết tay bằng bút cảm ứng hay không. Gọi sự kiện này phương thức trước mỗi lệnh gọi đến InputMethodManager#startStylusHandwriting() vì tính năng viết tay có thể đã thay đổi.

  • InputMethodManager#startStylusHandwriting() — Yêu cầu IME chuyển sang chế độ viết tay. Một ACTION_CANCEL sự kiện chuyển động được gửi đến ứng dụng để huỷ cử chỉ hiện tại. Bút cảm ứng không còn được gửi đến ứng dụng nữa.

    Sự kiện chuyển động bằng bút cảm ứng của cử chỉ hiện tại đã được gửi đến ứng dụng sẽ được chuyển tiếp đến IME. Cần có IME để hiển thị mực của bút cảm ứng cửa sổ mà qua đó IME nhận tất cả đối tượng MotionEvent sau đây. IME xác nhận văn bản viết tay bằng cách sử dụng InputConnection API.

    Nếu IME không thể vào chế độ viết tay, thì lệnh gọi phương thức này không hoạt động.

Khai báo tính năng hỗ trợ chữ viết tay

Khi điền vào Đối số EditorInfo trong số View#onCreateInputConnection(EditorInfo) cuộc gọi setStylusHandwritingEnabled() để thông báo cho IME rằng trình chỉnh sửa văn bản hỗ trợ chữ viết tay. Khai báo các cử chỉ được hỗ trợ bằng setSupportedHandwritingGestures()setSupportedHandwritingGesturePreviews().

Hỗ trợ cử chỉ viết tay

IME có thể hỗ trợ nhiều cử chỉ viết tay, chẳng hạn như khoanh tròn văn bản để chọn hoặc vẽ phác lên văn bản để xoá.

Hình 2. Khoanh tròn để chọn văn bản.
Hình 3. Vẽ nguệch ngoạc để xoá văn bản.

Triển khai trình chỉnh sửa tuỳ chỉnh InputConnection#performHandwritingGesture()InputConnection#previewHandwritingGesture() để hỗ trợ các báo cáo khác nhau HandwritingGesture các loại, chẳng hạn như SelectGesture, DeleteGestureInsertGesture.

Khai báo các cử chỉ viết tay được hỗ trợ khi điền đối số EditorInfo trên View#onCreateInputConnection(EditorInfo) (xem phần Khai báo chữ viết tay support).

Thông tin chi tiết về API

  • InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer) — Triển khai các cử chỉ. Đối số HandwritingGesture chứa thông tin vị trí mà bạn có thể sử dụng để xác định vị trí cần đến trong văn bản thực hiện cử chỉ đó. Ví dụ: SelectGesture cung cấp RectF đối tượng chỉ định phạm vi văn bản đã chọn và InsertGesture cung cấp PointF đối tượng chỉ định độ lệch văn bản mà tại đó sẽ chèn văn bản.

    Sử dụng Executor và Thông số IntConsumer để gửi lại kết quả của thao tác. Khi cả người thực thi và đối số dành cho người tiêu dùng được cung cấp, hãy sử dụng bộ thực thi để gọi IntConsumer#accept()! ví dụ:

    
    executor.execute { consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS) }
    
    
  • HandwritingGesture#getFallbackText() — Cung cấp văn bản dự phòng mà IME gửi ở vị trí con trỏ nếu không có văn bản thích hợp nằm dưới khu vực của cử chỉ viết tay.

    Đôi khi, IME không thể xác định liệu cử chỉ dùng bút cảm ứng có nhằm thực hiện một thao tác cử chỉ hoặc để viết tay văn bản. Văn bản tuỳ chỉnh biên tập viên chịu trách nhiệm xác định ý định của người dùng và thực hiện thao tác thích hợp (tuỳ thuộc vào ngữ cảnh) tại vị trí cử chỉ.

    Ví dụ: nếu IME không thể xác định liệu người dùng có định vẽ con nháy hướng xuống ⋁ để thực hiện cử chỉ chèn dấu cách hoặc viết tay chữ cái "v" IME có thể gửi InsertGesture có văn bản dự phòng là "v".

    Trước tiên, trình chỉnh sửa nên cố gắng thực hiện cử chỉ chèn dấu cách. Nếu không thể thực hiện cử chỉ (ví dụ: không có văn bản nào tại vị trí này đã chỉ định), trình chỉnh sửa sẽ quay lại chèn "v" tại con trỏ vị trí.

  • InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal) — Xem trước một cử chỉ đang diễn ra. Ví dụ: khi người dùng bắt đầu vẽ một vòng tròn xung quanh một số văn bản, thì bạn có thể xem trước trực tiếp lựa chọn thu được hiển thị và liên tục được cập nhật khi người dùng tiếp tục vẽ. Chỉ một số loại cử chỉ có thể xem trước được (xem PreviewableHandwritingGesture).

    IME có thể sử dụng tham số CancellationSignal để huỷ bản xem trước. Nếu các sự kiện khác làm gián đoạn bản xem trước (ví dụ: văn bản bị thay đổi có lập trình hoặc lệnh InputConnection mới xảy ra), trình chỉnh sửa tuỳ chỉnh có thể huỷ bản xem trước.

    Cử chỉ xem trước chỉ dùng để hiển thị và không thay đổi trạng thái. Ví dụ: bản xem trước SelectGesture sẽ ẩn nội dung hiện tại của trình chỉnh sửa vùng chọn và đánh dấu phạm vi xem trước cử chỉ. Nhưng khi bản xem trước bị huỷ, trình chỉnh sửa sẽ khôi phục dải ô được chọn trước đó.

Cung cấp vị trí con trỏ và dữ liệu khác về vị trí

Ở chế độ viết tay, IME có thể yêu cầu vị trí con trỏ và các dữ liệu vị trí khác đang sử dụng InputConnection#requestCursorUpdates(). Trình chỉnh sửa tuỳ chỉnh phản hồi bằng một lệnh gọi đến InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo). Dữ liệu trong CursorAnchorInfo liên quan đến chữ viết tay bằng bút cảm ứng được cung cấp thông qua CursorAnchorInfo.Builder phương thức:

  • setInsertionMarkerLocation() — Đặt vị trí của con trỏ. IME sử dụng giá trị để tạo ảnh động viết tay cho vị trí con trỏ.
  • setEditorBoundsInfo() — Thiết lập giới hạn cho trình chỉnh sửa và giới hạn chữ viết tay. IME sử dụng dữ liệu này để định vị thanh công cụ chữ viết tay của IME trên màn hình.
  • addVisibleLineBounds() — Đặt ranh giới của tất cả các dòng văn bản hiển thị (hoặc hiển thị một phần) của trình chỉnh sửa. IME sử dụng giới hạn dòng để cải thiện độ chính xác trong việc nhận dạng cử chỉ viết tay.
  • setTextAppearanceInfo() — Thiết lập giao diện văn bản với thông tin thu được từ văn bản trường nhập dữ liệu. IME sử dụng thông tin này để tạo kiểu cho mực viết tay.

Hiện biểu tượng di chuột viết tay bằng bút cảm ứng

Hiển thị biểu tượng di chuột viết tay bằng bút cảm ứng khi bút cảm ứng di chuột qua ranh giới chữ viết tay của trình chỉnh sửa văn bản tuỳ chỉnh và IME đã chọn hỗ trợ viết tay bằng bút cảm ứng (InputMethodManager#isStylusHandwritingAvailable()).

Ghi đè View#onResolvePointerIcon() để nhận biểu tượng di chuột cho chữ viết tay bằng bút cảm ứng. Trong chế độ ghi đè, hãy gọi PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING) để truy cập vào biểu tượng di chuột viết tay bằng bút cảm ứng của hệ thống.

Tài nguyên khác