ویرایشگر روش ورودی (IME) یک کنترل کاربر است که به کاربران امکان میدهد نوشتار وارد کنند. Android چارچوب روش ورودی توسعهپذیری ارائه میدهد که به برنامهها امکان میدهد روشهای ورودی جایگزین، مثل صفحهکلید مجازی یا ورودی گفتاری، را دراختیار کاربران قرار دهند. پساز نصب «روشهای ورودی»، کاربر میتواند یکی از آنها را در تنظیمات سیستم انتخاب کند و در کل سیستم از آن استفاده کند. هربار فقط یک IME میتواند فعال باشد.
برای افزودن «روش ورودی» به سیستم Android، برنامه Android حاوی کلاسی ایجاد کنید که
InputMethodService را
گسترش دهد.
علاوهبراین، معمولاً فعالیت «تنظیمات» ایجاد میکنید که گزینهها را به سرویس IME ارسال میکند. همچنین میتوانید یک واسط کاربر تنظیمات تعریف کنید که بهعنوان بخشی از تنظیمات سیستم نمایش داده میشود.
این صفحه موضوعات زیر را پوشش میدهد:
- چرخه حیات IME
- اعلام کردن عناصر IME در مانیفست برنامه
- میانای برنامهسازی کاربردی IME
- طراحی میانای کاربر IME
- ارسال نوشتار از «ویرایشگر روش ورودی» به برنامه
- کار کردن با انواع فرعی IME
- ملاحظات دیگر درباره IME
اگر با «روشهای ورودی» کار نکردهاید، ابتدا مقاله مقدماتی روشهای ورودی روی صفحه را بخوانید.
چرخه حیات IME
نمودار زیر چرخه زندگی «ویرایشگر روش ورودی» را توصیف میکند:
بخشهای زیر نحوه پیادهسازی رابط کاربری و کد مرتبط با «ویرایشگر روش ورودی» را که از این چرخه حیات پیروی میکند شرح میدهد.
اعلام کردن عناصر IME در مانیفست
در سیستم Android، «روش ورودی» برنامه Android است که حاوی سرویس ویژه «روش ورودی» است. فایل مانیفست برنامه باید سرویس را تعریف کند، اجازههای لازم را درخواست کند، فیلتر هدفی ارائه دهد که با کنش action.view.InputMethod مطابقت داشته باشد، و فرادادهای ارائه دهد که ویژگیهای IME را تعریف کند. علاوهبراین، برای ارائه کردن میانای تنظیمات که به کاربر اجازه میدهد رفتار «روش ورودی» را تغییر دهد، میتوانید فعالیت «تنظیمات» را تعریف کنید که میتواند از «تنظیمات سیستم» راهاندازی شود.
تکه کد زیر سرویس IME را اعلام میکند. این سرویس اجازه
BIND_INPUT_METHOD
را درخواست میکند تا به آن اجازه دهد «روش ورودی» را به سیستم متصل کند، فیلتر هدفی را راهاندازی میکند که با کنش
android.view.InputMethod مطابقت دارد، و فراداده را برای «روش ورودی» تعریف میکند:
<!-- Declares the input method service. --> <service android:name="FastInputIME" andro@id:label="string/fast_input_label" android:permission="android.perm>issio<n.BIND_INPUT_>METHOD&qu<ot; intent-filter action android:nam>e=&qu<ot;android.vie>w.Inp<utMethod" / /intent-filter meta-data android:name="andro@id.view.im&qu>o<t; > android:resource="xml/method" / /service
گزیده بعدی فعالیت تنظیمات را برای IME اعلام میکند. این برنامه فیلتر هدفی برای
ACTION_MAIN دارد که
نشان میدهد این فعالیت نقطه ورود اصلی برای برنامه IME است:
<!-- Optional: an activity for controlling the IME settings. --> <activity android:name="FastInputIMESettings" andro@id:label="string/fast_>input<_settings&quo>t; in<tent-filter action android:name="and>roid.<intent.action.>M<AIN">/ /intent-filter /activity
همچنین میتوانید مستقیماً از رابط کاربری آن، دسترسی به تنظیمات IME را فراهم کنید.
میانای برنامهسازی کاربردی روش ورودی
کلاسهای مربوط به «روشهای ورودی» در
android.inputmethodservice
و
android.view.inputmethod
بستهها پیدا میشوند. کلاس KeyEvent برای مدیریت نویسههای صفحهکلید مهم است.
بخش مرکزی «ویرایشگر روش ورودی» یک عنصر سرویس است—کلاسی که
InputMethodService را گسترش میدهد. علاوهبر پیادهسازی چرخه حیات سرویس معمولی، این کلاس دارای
بازخوانهایی برای ارائه کردن واسط کاربر IME شما، مدیریت ورودی کاربر، و ارائه کردن نوشتار به
فیلدی است که تمرکز دارد. بهطور پیشفرض، کلاس InputMethodService بیشتر پیادهسازیهای مربوط به مدیریت وضعیت و رؤیتپذیری IME و ارتباط با فیلد ورودی فعلی را ارائه میدهد.
کلاسهای زیر نیز مهم هستند:
BaseInputConnection-
کانال ارتباطی را از
InputMethodبه برنامهای که ورودی آن را دریافت میکند تعریف میکند. از آن برای خواندن نوشتار اطراف مکاننما، سپردن نوشتار به چارگوش نوشتاری، و ارسال رویدادهای کلید خام به برنامه استفاده میکنید. برنامهها باید این کلاس را گسترش دهند و رابط پایهInputConnectionرا پیادهسازی نکنند. KeyboardView-
افزونهای از
Viewکه صفحهکلید را پرداز میکند و به رویدادهای ورودی کاربر پاسخ میدهد. چیدمان صفحهکلید با نمونهای ازKeyboardمشخص میشود که میتوانید آن را در فایل XML تعریف کنید.
طراحی واسط کاربر روش ورودی
دو عنصر دیداری اصلی برای «ویرایشگر روش ورودی» وجود دارد: نمای ورودی و نمای نامزدها. فقط باید عناصری را پیادهسازی کنید که با روش ورودیای که طراحی میکنید مرتبط هستند.
نمای ورودی
نمای ورودی میانای کاربری است که کاربر در آن نوشتار را بهصورت کلیکهای کلید، دستنویسی، یا اشاره وارد میکند. وقتی IME برای اولینبار نمایش داده میشود، سیستم
onCreateInputView()
بازخوان را فرا میخواند. در پیادهسازی این روش، چیدمانی را که میخواهید در پنجره IME نمایش داده شود ایجاد کنید و چیدمان را به سیستم برگردانید. تکهکد زیر نمونهای از پیادهسازی
روش onCreateInputView() را نشان میدهد:
کاتلین
override fun onCreateInputView(): View { return layoutInflater.inflate(R.layout.input, null).apply { if (this is MyKeyboardView) { setOnKeyboardActionListener(this@MyInputMethod) keyboard = latinKeyboard } } }
جاوا
@Override public View onCreateInputView() { MyKeyboardView inputView = (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null); inputView.setOnKeyboardActionListener(this); inputView.setKeyboard(latinKeyboard); return inputView; }
در این مثال، MyKeyboardView نمونهای از پیادهسازی سفارشی KeyboardView است که Keyboard را ارائه میکند.
نمای نامزدها
نمای نامزدها رابط کاربریای است که در آن «ویرایشگر روش ورودی» اصلاحات یا پیشنهادهای احتمالی کلمه را برای انتخاب کاربر نمایش میدهد. در چرخه حیات IME، سیستم
onCreateCandidatesView()
را زمانی که آماده نمایش نمای نامزدها است فرا میخواند. در پیادهسازی این روش، چیدمانی برگردانید که پیشنهادهای کلمه را نشان دهد، یا اگر نمیخواهید چیزی نشان دهید، مقدار null برگردانید. پاسخ تهی رفتار پیشفرض است، بنابراین اگر پیشنهاد ارائه نمیدهید، لازم نیست این مورد را پیادهسازی کنید.
ملاحظات طراحی میانای کاربر
این بخش برخیاز ملاحظات طراحی رابط کاربری برای «ویرایشگرهای روش ورودی» را شرح میدهد.
مدیریت اندازههای مختلف صفحهنمایش
«میانای کاربری» برای «روش ورودی» شما باید بتواند برای اندازههای مختلف صفحهنمایش مقیاسبندی شود و از هر دو جهت افقی و عمودی پشتیبانی کند. در حالت IME غیرتمامصفحه، فضای کافی برای برنامه بگذارید تا فیلد نوشتار و هر بافت مرتبطی را نشان دهد، بهطوری که IME بیشاز نیمی از صفحه را اشغال نکند. در حالت تمامصفحه IME، این مشکل وجود ندارد.
مدیریت انواع مختلف ورودی
فیلدهای نوشتاری Android به شما امکان میدهند نوع ورودی خاصی را تنظیم کنید، مثلاً نوشتار آزاد، اعداد، نشانیهای وب، نشانیهای ایمیل، و رشتههای جستجو. وقتی «ویرایشگر روش ورودی» جدیدی را پیادهسازی میکنید، نوع ورودی هر فیلد را تشخیص دهید و رابط مناسب را برای آن ارائه دهید. بااینحال، لازم نیست IME خود را برای بررسی اینکه کاربر نوشتار معتبری برای نوع ورودی وارد میکند یا نه راهاندازی کنید. این مسئولیت برنامه مالک فیلد نوشتاری است.
برای مثال، در اینجا میانایی را میبینید که «ویرایشگر روش ورودی لاتین» برای ورودی نوشتاری پلاتفرم Android ارائه میدهد:
و در اینجا رابطی است که «ویرایشگر روش ورودی لاتین» برای پلاتفرم Android ارائه میدهد ورودی عددی:
وقتی فیلد ورودی تمرکز را دریافت میکند و «روش ورودی» شما شروع میشود، سیستم
onStartInputView() را فرا میخواند و
EditorInfo شیئی را
که حاوی جزئیات مربوط به نوع ورودی و دیگر مشخصههای فیلد نوشتاری است، ارسال میکند. در این شیء،
فیلد
inputType
حاوی نوع ورودی فیلد نوشتار است.
فیلد inputType یک int است که حاوی الگوهای بیت برای تنظیمات مختلف نوع ورودی است. برای آزمایش آن برای نوع ورودی فیلد نوشتاری، آن را با ثابت
TYPE_MASK_CLASS،
به این صورت پوشش دهید:
کاتلین
inputType and InputType.TYPE_MASK_CLASS
جاوا
inputType & InputType.TYPE_MASK_CLASS
الگوی بیت نوع ورودی میتواند یکی از چندین مقدار زیر را داشته باشد:
TYPE_CLASS_NUMBER- فیلد نوشتاری برای وارد کردن اعداد. همانطور که در شکل ۳ نشان داده شده است، «ویرایشگر روش ورودی» لاتین برای فیلدهای این نوع، صفحه کلید عددی نمایش میدهد.
TYPE_CLASS_DATETIME- فیلد نوشتاری برای وارد کردن تاریخ و زمان.
TYPE_CLASS_PHONE- فیلد نوشتاری برای وارد کردن شماره تلفن.
TYPE_CLASS_TEXT- فیلد نوشتاری برای وارد کردن نویسههای پشتیبانیشده.
این ثابتها در سند مرجع InputType با جزئیات بیشتری توضیح داده شدهاند.
فیلد inputType میتواند حاوی بخشهای دیگری باشد که نشاندهنده نوع متغیر فیلد نوشتاری است، مثل:
TYPE_TEXT_VARIATION_PASSWORD- گونهای از
TYPE_CLASS_TEXTبرای وارد کردن گذرواژهها. روش ورودی بهجای نوشتار واقعی نشانههای چاپ نمایش میدهد. TYPE_TEXT_VARIATION_URI- گونهای از
TYPE_CLASS_TEXTبرای وارد کردن نشانیهای وب و دیگر شناسههای منبع یکسان (URI). TYPE_TEXT_FLAG_AUTO_COMPLETE- گونهای از
TYPE_CLASS_TEXTبرای وارد کردن نوشتاری که برنامه آن را بهطور خودکار از واژهنامه، جستجو، یا امکانات دیگر تکمیل میکند.
وقتی این گونهها را آزمایش میکنید، inputType را با ثابت مناسبی بپوشانید. ثابتهای پوشش موجود در اسناد مرجع InputType فهرست شده است.
ارسال نوشتار به برنامه
وقتی کاربر با IME شما نوشتار وارد میکند، میتوانید با ارسال رویدادهای کلید جداگانه یا با ویرایش نوشتار اطراف مکاننما در فیلد نوشتاری برنامه، نوشتار را به برنامه ارسال کنید. در هر دو حالت،
از نمونه InputConnection برای ارائه نوشتار استفاده کنید. برای دریافت این نمونه، با
InputMethodService.getCurrentInputConnection() تماس بگیرید.
ویرایش کردن نوشتار اطراف مکاننما
وقتی درحال ویرایش نوشتار موجود هستید، برخیاز روشهای مفید در
BaseInputConnection عبارتاند از:
-
getTextBeforeCursor() CharSequenceحاوی تعداد نویسههای درخواستی قبلاز موقعیت مکاننمای فعلی را برمیگرداند.-
getTextAfterCursor() CharSequenceحاوی تعداد نویسههای درخواستشده را که پساز موقعیت مکاننمای کنونی قرار دارند برمیگرداند.-
deleteSurroundingText() - تعداد مشخصشده از نویسهها را قبل و بعداز موقعیت مکاننمای فعلی حذف میکند.
-
commitText() CharSequenceرا در فیلد نوشتار ثبت میکند و مکاننمای جدیدی تنظیم میکند.
برای مثال، تکهکد زیر نشان میدهد که چگونه چهار نویسه سمت چپ مکاننما را با نوشتار «سلام!» جایگزین کنید:
کاتلین
currentInputConnection.also { ic: InputConnection -> ic.deleteSurroundingText(4, 0) ic.commitText("Hello", 1) ic.commitText("!", 1) }
جاوا
InputConnection ic = getCurrentInputConnection(); ic.deleteSurroundingText(4, 0); ic.commitText("Hello", 1); ic.commitText("!", 1);
پشتیبانی از نوشتن نوشتار قبلاز قطعی کردن
اگر «ویرایشگر روش ورودی» شما نوشتار را پیشبینی میکند یا برای ترکیب یک گلیک یا کلمه به چند مرحله نیاز دارد، میتوانید پیشرفت را در فیلد نوشتار نشان دهید تا کاربر کلمه را تأیید کند، و سپس میتوانید ترکیب جزئی را با نوشتار کامل جایگزین کنید. وقتی نوشتار را به
setComposingText() ارسال میکنید، میتوانید با افزودن
span به آن، نوشتار را برجسته کنید.
تکهکد زیر نشان میدهد که چگونه پیشرفت را در فیلد نوشتاری نشان دهید:
کاتلین
currentInputConnection.also { ic: InputConnection -> ic.setComposingText("Composi", 1) ic.setComposingText("Composin", 1) ic.commitText("Composing ", 1) }
جاوا
InputConnection ic = getCurrentInputConnection(); ic.setComposingText("Composi", 1); ic.setComposingText("Composin", 1); ic.commitText("Composing ", 1);
رویدادهای کلید سختافزاری را رهگیری کنید
حتی اگر پنجره روش ورودی تمرکز صریحی نداشته باشد، رویدادهای کلید سختافزاری را ابتدا دریافت میکند و میتواند آنها را مصرف کند یا به برنامه ارسال کند. برای مثال، ممکن است بخواهید از کلیدهای جهتدار برای پیمایش در میان واسط کاربر برای انتخاب نامزد درحین نوشتن استفاده کنید. همچنین ممکن است بخواهید کلید برگشت را برای بستن هرگونه چارگوش گفتگویی که از پنجره روش ورودی منشأ میگیرد بهکار ببرید.
برای رهگیری کلیدهای سختافزاری،
onKeyDown()
و
onKeyUp() را ملغی کنید.
برای کلیدهایی که نمیخواهید خودتان مدیریت کنید، روش super() را فراخوانی کنید.
ایجاد زیرنوع IME
زیرنوعها به «روش ورودی» اجازه میدهند چندین زبان و حالت ورودی پشتیبانیشده توسط «روش ورودی» را آشکار کند. زیرنوع میتواند نشاندهنده موارد زیر باشد:
- منطقه زبانی، مثل en_US یا fr_FR
- حالت ورودی، مثل صدا، صفحهکلید، یا دستنویسی
- سبکهای ورودی، فرمها، یا ویژگیهای دیگر مختص IME، مثل جانماییهای صفحهکلید ۱۰ کلیدی یا QWERTY
حالت میتواند هر نوشتاری باشد، مثلاً «صفحهکلید» یا «صدا». زیرنوع میتواند ترکیبی از این موارد را نیز آشکار کند.
از اطلاعات زیرنوع برای کادر گفتگوی تعویضکننده IME که از نوار اعلان دردسترس است و برای تنظیمات IME استفاده میشود. این اطلاعات همچنین به چارچوب اجازه میدهد تا مستقیماً یک زیرنوع خاص از IME را نمایش دهد. وقتی IME میسازید، از امکانات نوع فرعی استفاده کنید، زیرا به کاربر کمک میکند زبانها و حالتهای مختلف IME را شناسایی کند و بین آنها جابهجا شود.
زیرنوعها را در یکی از فایلهای منبع XML روش ورودی بااستفاده از عنصر
<subtype> تعریف کنید. تکه کد زیر یک «روش ورودی» را با دو زیرنوع تعریف میکند: زیرنوع صفحهکلید برای منطقه زبانی انگلیسی ایالات متحده و زیرنوع صفحهکلید دیگر برای منطقه زبانی فرانسوی برای فرانسه:
<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.softkeyboard.Settings" @ android:icon>=&quo<t;drawable/ime_icon&qu@ot; subtype android:name="string/display_name_english_keybo@ard_ime" android:icon="drawable/subtype_icon_english_keyboard_ime" android:languageTag="en-US" android:imeSubtypeMode="keyboard&quo>t; < android:imeS@ubtypeExtraValue="somePrivateOption=true" / subtype a@ndroid:name="string/display_name_french_keyboard_ime" android:icon="drawable/subtype_icon_french_keyboard_ime" android:languageTag="fr-FR" android:i>meSub<typeMode="keyboar@d" android:imeSubtypeExtraVal>u<e="someV>ariable=30,someInternalOption=false" / subtype android:name="string/display_name_german_keyboard_ime" ... / /input-method
برای اطمینان از اینکه زیرنوعهایتان در «میانای کاربر» بهدرستی برچسبگذاری میشوند، از `%s` استفاده کنید تا برچسب زیرنوعی دریافت کنید که با برچسب محلی زیرنوع یکسان است. این موضوع در دو تکهکد بعدی نشان داده شده است. اولین تکهکد بخشی از فایل XML روش ورودی را نشان میدهد:
<subtype android:label=&@quot;string/label_subtype_generic" android:imeSubtypeLocale="en_US"@; android:icon="drawable/icon_en_us" andro>id:imeSubtypeMode="keyboard" /
تکهکد بعدی بخشی از فایل strings.xml «ویرایشگر روش ورودی» است. منبع رشتهای
label_subtype_generic که در تعریف میانای کاربر روش ورودی برای تنظیم برچسب
نوع فرعی استفاده میشود بهصورت زیر تعریف شده است:
<string name="label_subtype_gen>er<ic">;%s/stringاین تنظیم باعث میشود نام نمایشی زیرنوع با تنظیمات محلی مطابقت داشته باشد. برای مثال، در هر منطقه انگلیسی، نام نمایشی «انگلیسی (ایالات متحده)» است.
انتخاب کردن انواع فرعی «روش ورودی» از نوار اعلان
سیستم Android همه زیرنوعهای نمایانشده توسط همه «روشهای ورودی» را مدیریت میکند. زیرنوعهای IME بهعنوان حالتهای IME که به آن تعلق دارند درنظر گرفته میشوند. کاربر میتواند از نوار اعلان یا برنامه «تنظیمات» به منو زیرنوعهای IME دردسترس پیمایش کند، همانطور که در شکل زیر نشان داده شده است:
زیرنوعهای «روش ورودی» را از «تنظیمات سیستم» انتخاب کنید
کاربر همچنین میتواند نحوه استفاده از زیرنوعها را در پانل تنظیمات زبان و ورودی در تنظیمات سیستم کنترل کند:
جابهجایی بین انواع فرعی IME
با ارائه کلید جابهجایی، مثل نماد زبان کرویشکل روی صفحهکلید، میتوانید به کاربران امکان دهید بهراحتی بین انواع فرعی IME جابهجا شوند. این کار کاربردپذیری صفحهکلید را بهبود میبخشد و برای کاربر راحت است. برای فعال کردن این تعویض، مراحل زیر را انجام دهید:
-
supportsSwitchingToNextInputMethod = "true"را در فایلهای منبع XML روش ورودی اعلام کنید. اظهارنامه شما باید شبیه تکهکد زیر باشد:<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.softkeyboard.Settings" @ android:icon="drawable/ime_icon" android:supportsSwi>tchingToNextInputMethod="true"
- روش
shouldOfferSwitchingToNextInputMethod()را فراخوانی کنید. - اگر روش درست برگرداند، کلید تعویضی را نمایش دهید.
- وقتی کاربر روی کلید جابهجایی ضربه میزند،
با ارسال مقدار نادرست، با
switchToNextInputMethod()تماس بگیرید. مقدار نادرست به سیستم میگوید که با همه انواع فرعی بهطور یکسان رفتار کند، صرفنظر از اینکه به کدام IME تعلق دارند. اگر مقدار true مشخص شود، سیستم باید در IME کنونی از میان انواع فرعی عبور کند.
ملاحظات کلی «ویرایشگر روش ورودی»
در اینجا موارد دیگری وجود دارد که باید هنگام پیادهسازی IME خود در نظر بگیرید:
- روشی برای کاربران فراهم کنید تا گزینهها را مستقیماً از واسط کاربر IME تنظیم کنند.
- راهی برای کاربران فراهم کنید تا مستقیماً از واسط کاربری روش ورودی به «ویرایشگر روش ورودی» دیگری بروند، زیرا ممکن است چندین «ویرایشگر روش ورودی» در دستگاه نصب شده باشد.
- بهسرعت واسط کاربر IME را بالا بیاورید. منابع بزرگ را ازقبل بار کنید یا درصورت نیاز بار کنید تا کاربران بهمحض تکضرب زدن روی فیلد نوشتاری، «ویرایشگر روش ورودی» را ببینند. منابع و نماها را برای فراخوانیهای بعدی روش ورودی ذخیره میکند.
- تخصیصهای حافظه بزرگ را بلافاصله پساز پنهان شدن پنجره روش ورودی آزاد کنید تا برنامهها حافظه کافی برای اجرا داشته باشند. اگر IME برای چند ثانیه پنهان شود، از پیام تأخیری برای آزاد کردن منابع استفاده کنید.
- مطمئن شوید که کاربران بتوانند تا حد امکان نویسههای زیادی را برای زبان یا منطقهای که با IME مرتبط است وارد کنند. کاربران ممکن است از نشانههای سجاوندی در گذرواژهها یا نامهای کاربری استفاده کنند، بنابراین «روش ورودی» شما باید نویسههای مختلفی را ارائه دهد تا کاربران بتوانند گذرواژه وارد کنند و به دستگاه دسترسی پیدا کنند.