ویرایشگرهای متن سفارشی

ویرایشگرهای متن سفارشی، نماهایی هستند که اجزای EditText یا ابزارک‌های متنی WebView نیستند، اما با این وجود، با اجرای callback onCreateInputConnection() ورودی متن پشتیبانی می‌کنند، که زمانی فراخوانی می‌شود که یک view متمرکز شده باشد و سیستم یک InputConnection برای view درخواست کند.

فراخوانی به onCheckIsTextEditor() از یک ویرایشگر متن سفارشی باید true باشد.

پشتیبانی از دست خط قلم در ویرایشگرهای متن سفارشی

Android 14 (سطح API 34) و بالاتر به طور پیش‌فرض از ورودی قلم در اجزای ورودی متن استاندارد Android پشتیبانی می‌کنند (به ورودی قلم در فیلدهای نوشتاری مراجعه کنید). با این حال، فیلدهای ورودی متن سفارشی (یا ویرایشگرها) نیاز به توسعه بیشتری دارند.

برای ایجاد یک ویرایشگر متن سفارشی، موارد زیر را انجام دهید:

  1. شروع دست خط را فعال کنید
  2. حمایت از دست خط را اعلام کنید
  3. پشتیبانی از حرکات دست خط (انتخاب، حذف، درج و غیره)
  4. مکان مکان نما و سایر داده های موقعیت را به IME ارائه دهید
  5. نماد شناور دست خط قلم را نشان دهید

شروع دست خط را فعال کنید

اگر یک نما فقط از یک ویرایشگر متن تشکیل شده باشد، سیستم view می تواند به طور خودکار دستخط قلم را برای نما شروع کند. در غیر این صورت، view باید منطق شروع دست خط خود را پیاده کند.

شروع خودکار دست خط

اگر یک نما یک ویرایشگر متن و هیچ محتوای دیگری را نمایش نمی‌دهد، نما می‌تواند با فراخوانی setAutoHandwritingEnabled(true) در شروع خودکار دست‌نویس سیستم view شرکت کند.

با فعال کردن دست‌نویس خودکار، حرکت قلم که در هر جایی در محدوده دست‌نویس نما شروع می‌شود، به‌طور خودکار حالت دست‌نویس را آغاز می‌کند. ویرایشگر روش ورودی ( IME ) رویدادهای حرکت قلم را دریافت می کند و متن شناسایی شده را متعهد می کند.

فیلد ورودی با مستطیل اطراف که مرزهای تشخیص رویدادهای حرکت قلم را نشان می دهد.
شکل 1. دست خط در محدوده یک فیلد EditText .

شروع دستخط سفارشی

اگر یک نما علاوه بر یک ویرایشگر متن دارای چندین ویرایشگر متن یا محتوا باشد، نما باید منطق شروع دست خط خود را به صورت زیر پیاده سازی کند:

  1. با فراخوانی setAutoHandwritingEnabled(false) از شروع خودکار دست خط سیستم view انصراف دهید.

  2. تمام ویرایشگرهای متنی که در نمای قابل مشاهده هستند را پیگیری کنید.

  3. رویدادهای حرکتی دریافت شده توسط view را در dispatchTouchEvent() نظارت کنید.

    • هنگامی که حرکت قلم در محدوده دست خط یک ویرایشگر متن رخ می دهد، ویرایشگر متن را متمرکز کنید (اگر قبلاً فوکوس نشده است).

    • اگر ویرایشگر قبلاً متمرکز نشده بود، IME ویرایشگر را با محتویات جدید با فراخوانی InputMethodManager#restartInput() راه اندازی مجدد کنید.

    • جلسه دست‌نویسی قلم را با فراخوانی InputMethodManager#startStylusHandwriting() شروع کنید.

اگر یک ویرایشگر متن در یک نمای قابل پیمایش باشد، حرکت قلم در محدوده دست خط ویرایشگر باید به عنوان دست خط در نظر گرفته شود، نه پیمایش. از ViewParent#requestDisallowInterceptTouchEvent() استفاده کنید تا یک نمای اجدادی قابل پیمایش از رهگیری رویدادهای لمسی از یک ویرایشگر متن جلوگیری کنید.

جزئیات API

  • MotionEvent#getToolType() - نشان می دهد که آیا MotionEvent از یک قلم است، در این صورت مقدار بازگشتی TOOL_TYPE_STYLUS یا TOOL_TYPE_ERASER است.

  • InputMethodManager#isStylusHandwritingAvailable() - نشان می دهد که آیا IME از دستخط قلم پشتیبانی می کند یا خیر. این متد را قبل از هر تماس با InputMethodManager#startStylusHandwriting() فراخوانی کنید زیرا ممکن است در دسترس بودن دست خط تغییر کرده باشد.

  • InputMethodManager#startStylusHandwriting() - باعث می شود IME وارد حالت دست خط شود. یک رویداد حرکتی ACTION_CANCEL برای لغو حرکت فعلی به برنامه ارسال می‌شود. رویدادهای حرکت قلم دیگر به برنامه ارسال نمی شود.

    رویدادهای حرکت قلم مربوط به حرکت فعلی که قبلاً به برنامه ارسال شده بودند به IME بازارسال می‌شوند. IME باید یک پنجره جوهر قلم را نشان دهد که از طریق آن IME تمام اشیاء MotionEvent زیر را دریافت می کند. IME با استفاده از APIهای InputConnection ، متن دست خط شناسایی شده را متعهد می کند.

    اگر 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" ارسال کند.

    ویرایشگر ابتدا باید سعی کند ژست insert space را انجام دهد. اگر ژست قابل انجام نباشد (مثلاً متنی در مکان مشخص شده وجود ندارد)، ویرایشگر باید به درج "v" در موقعیت مکان نما بازگردد.

  • InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal) — یک حرکت در حال انجام را پیش نمایش می دهد. به عنوان مثال، هنگامی که کاربر شروع به کشیدن دایره ای در اطراف متنی می کند، می توان پیش نمایشی زنده از انتخاب به دست آمده نشان داد و به طور مداوم در حین ادامه طراحی کاربر به روز رسانی کرد. فقط انواع خاصی از اشاره قابل پیش‌نمایش هستند (به PreviewableHandwritingGesture مراجعه کنید).

    پارامتر CancellationSignal می تواند توسط IME برای لغو پیش نمایش استفاده شود. اگر رویدادهای دیگر پیش‌نمایش را مختل کنند (مثلاً متن از طریق برنامه‌ریزی تغییر کند یا دستورات جدید 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) را برای دسترسی به نماد شناور دستخط قلم سیستم تماس بگیرید.

منابع اضافی