قابلیت مشاهده روش ورودی را کنترل کنید

هنگامی که فوکوس ورودی به داخل یا خارج از یک فیلد نوشتاری قابل ویرایش حرکت می‌کند، Android ورودی را -مانند صفحه‌کلید روی صفحه- در صورت لزوم نشان می‌دهد یا پنهان می‌کند. سیستم همچنین تصمیم می گیرد که چگونه رابط کاربری و فیلد متنی شما در بالای روش ورودی ظاهر شوند. به عنوان مثال، وقتی فضای عمودی روی صفحه محدود است، قسمت متن ممکن است تمام فضای بالای روش ورودی را پر کند.

برای اکثر برنامه‌ها، این رفتارهای پیش‌فرض تمام چیزی است که لازم است. با این حال، در برخی موارد، ممکن است بخواهید کنترل بیشتری روی قابلیت مشاهده روش ورودی و نحوه تأثیر آن بر طرح‌بندی داشته باشید. این درس نحوه کنترل و پاسخ به قابلیت مشاهده روش ورودی را توضیح می دهد.

هنگام شروع فعالیت، صفحه کلید نرم را نشان دهید

اگرچه Android هنگام شروع فعالیت به اولین فیلد نوشتاری در طرح شما تمرکز می کند، اما صفحه کلید نرم را نشان نمی دهد. این رفتار مناسب است زیرا وارد کردن متن ممکن است وظیفه اصلی در فعالیت نباشد. با این حال، اگر وارد کردن متن واقعاً وظیفه اصلی است، مانند صفحه ورود به سیستم، احتمالاً می خواهید صفحه کلید نرم به طور پیش فرض ظاهر شود.

برای نشان دادن روش ورودی هنگام شروع فعالیت، ویژگی android:windowSoftInputMode به عنصر <activity> با مقدار "stateVisible" اضافه کنید. به عنوان مثال:

<application ... >
    <activity
        android:windowSoftInputMode="stateVisible" ... >
        ...
    </activity>
   ...
</application>

نحوه پاسخگویی رابط کاربری خود را مشخص کنید

وقتی صفحه کلید نرم روی صفحه نمایش ظاهر می شود، فضای موجود برای رابط کاربری برنامه شما را کاهش می دهد. سیستم تصمیم می گیرد که چگونه قسمت قابل مشاهده UI شما را تنظیم کند، اما ممکن است آن را درست انجام ندهد. برای اطمینان از بهترین رفتار برای برنامه خود، مشخص کنید که می خواهید سیستم چگونه رابط کاربری شما را در فضای باقیمانده نمایش دهد.

برای اعلام درمان ترجیحی خود در یک فعالیت، از ویژگی android:windowSoftInputMode در عنصر <activity> مانیفست خود با یکی از مقادیر "adjust" استفاده کنید.

به عنوان مثال، برای اطمینان از اینکه سیستم اندازه طرح‌بندی شما را به فضای موجود تغییر می‌دهد - که تمام محتوای طرح‌بندی شما را در دسترس نگه می‌دارد، حتی اگر نیاز به پیمایش داشته باشد، از "adjustResize" استفاده کنید:

<application ... >
   <activity
       android:windowSoftInputMode="adjustResize" ... >
       ...
   </activity>
   ...
</application>

می توانید مشخصات تنظیم را با مشخصات دید اولیه صفحه کلید نرم از بخش قبل ترکیب کنید:

<activity
    android:windowSoftInputMode="stateVisible|adjustResize" ... >
    ...
</activity>

تعیین "adjustResize" در صورتی مهم است که رابط کاربری شما شامل کنترل هایی باشد که کاربر ممکن است بلافاصله پس از یا در حین انجام ورودی متن به آنها دسترسی داشته باشد. به عنوان مثال، اگر از یک چیدمان نسبی برای قرار دادن نوار دکمه در پایین صفحه استفاده می کنید، با استفاده از "adjustResize" اندازه طرح تغییر می کند تا نوار دکمه در بالای صفحه کلید نرم ظاهر شود.

صفحه کلید نرم را در صورت تقاضا نشان دهید

اگر روشی در چرخه حیات فعالیت شما وجود دارد که می خواهید مطمئن شوید روش ورودی قابل مشاهده است، می توانید از InputMethodManager برای نمایش آن استفاده کنید.

به عنوان مثال، متد زیر یک View می گیرد که در آن کاربر انتظار می رود چیزی را تایپ کند، requestFocus() را فراخوانی می کند تا به آن تمرکز کند، سپس showSoftInput() را فراخوانی می کند تا روش ورودی را باز کند:

کاتلین

fun showSoftKeyboard(view: View) {
   if (view.requestFocus()) {
       val imm = getSystemService(InputMethodManager::class.java)
       imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
   }
}

جاوا

public void showSoftKeyboard(View view) {
   if (view.requestFocus()) {
       InputMethodManager imm = getSystemService(InputMethodManager.class);
       imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
   }
}

صفحه کلید نرم را با اطمینان نشان دهید

موقعیت‌های خاصی وجود دارد، مانند زمانی که یک فعالیت شروع می‌شود، که در آن استفاده از InputMethodManager.showSoftInput() برای نمایش صفحه‌کلید نرم ممکن است باعث شود صفحه‌کلید نرم‌افزار برای کاربر قابل مشاهده نباشد.

قابلیت مشاهده صفحه کلید نرم هنگام استفاده از showSoftInput() به شرایط زیر بستگی دارد:

  • نما باید قبلاً به صفحه کلید نرم افزار متصل باشد. (این، به نوبه خود، مستلزم آن است که پنجره فوکوس شود و نمای ویرایشگر فوکوس view را با View.requestFocus() درخواست کند).

  • دید نیز می تواند تحت تأثیر ویژگی android:windowSoftInputMode و پرچم های استفاده شده توسط showSoftInput() قرار گیرد.

در موارد استفاده خاص، مانند زمانی که یک فعالیت شروع می شود، برخی از این شرایط لازم برآورده نمی شوند. سیستم نما را متصل به صفحه کلید نرم افزار در نظر نمی گیرد، فراخوانی showSoftInput() را نادیده می گیرد و صفحه کلید نرم برای کاربر قابل مشاهده نیست.

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

  • (توصیه می شود) از WindowInsetsControllerCompat استفاده کنید. این شیء صفحه کلید نرم را در طول Activity.onCreate() نمایش می دهد همانطور که در قطعه کد زیر نشان داده شده است. زمان‌بندی تماس پس از فوکوس شدن پنجره تضمین می‌شود.

کاتلین

editText.requestFocus()
WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())

جاوا

editText.requestFocus();
WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());
  • یک runnable ارسال کنید. این تضمین می کند که برنامه شما قبل از فراخوانی showSoftInput() تا دریافت رویداد تمرکز پنجره از View.onWindowFocusChanged() صبر کند.

کاتلین

class MyEditText : EditText() {
  ...
  override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
    if (hasWindowFocus) {
      requestFocus()
      post {
        val imm: InputMethodManager = getSystemService(InputMethodManager::class.java)
        imm.showSoftInput(this, 0)
      }
    }
  }
}

جاوا

public class MyEditText extends EditText {
  ...
  @Override
  public void onWindowFocusChanged(boolean hasWindowFocus) {
    if (hasWindowFocus) {
      requestFocus();
      post(() -> {
        InputMethodManager imm = getSystemService(InputMethodManager.class);
        imm.showSoftInput(this, 0);
      });
    }
  }
}

پرچم‌های مشاهده زمان اجرا را با دقت مدیریت کنید

هنگام تغییر وضعیت نمایش صفحه کلید نرم در زمان اجرا، مراقب باشید که مقادیر پرچم خاصی را به این روش ها منتقل نکنید. به عنوان مثال، اگر برنامه انتظار دارد هنگام شروع فعالیت، هنگام فراخوانی View.getWindowInsetsController().show(ime()) در Activity.onCreate() صفحه کلید نرم ظاهر شود، توسعه دهندگان برنامه باید مراقب باشند که SOFT_INPUT_STATE_HIDDEN یا SOFT_INPUT_STATE_ALWAYS_HIDDEN را تنظیم نکنند. در هنگام راه اندازی اولیه در صورتی که صفحه کلید نرم به طور غیر منتظره پنهان شود.

سیستم معمولاً صفحه کلید نرم را به طور خودکار پنهان می کند

در بیشتر موقعیت‌ها، سیستم با مخفی کردن صفحه‌کلید نرم کار می‌کند. این می تواند یکی از موارد زیر باشد:

  • کاربر کار را در قسمت متن تمام می کند.
  • کاربر کلید برگشت را فشار می‌دهد یا با پیمایش پشت، حرکات انگشت خود را تند می‌کشد.
  • کاربر به برنامه دیگری پیمایش می‌کند، و آن برنامه دیگر زمانی که نمای فوکوس می‌کند، پرچم‌های SOFT_INPUT_STATE_HIDDEN یا SOFT_INPUT_STATE_ALWAYS_HIDDEN را تنظیم کرده است.

بر اساس رفتار سیستم قبلی، صفحه کلید نرم را به صورت دستی مخفی کنید

برنامه شما در برخی شرایط باید صفحه کلید نرم را به صورت دستی پنهان کند—مثلاً وقتی فیلد نوشتاری در View.OnFocusChangeListener.onFocusChange فوکوس خود را از دست می دهد. از این تکنیک با احتیاط استفاده کنید. بستن صفحه کلید نرم به طور غیرمنتظره ای به تجربه کاربر آسیب می رساند.

اگر برنامه شما به صورت دستی صفحه‌کلید نرم‌افزار را پنهان می‌کند، باید بدانید که آیا صفحه‌کلید نرم به‌طور صریح یا ضمنی نشان داده شده است:

  • در نظر گرفته می شود که صفحه کلید نرم پس از فراخوانی به showSoftInput() به صراحت نشان داده شده است.

  • برعکس، در نظر گرفته می شود که صفحه کلید نرم به طور ضمنی در یکی از شرایط زیر نشان داده شده است:

    • سیستم هنگام استفاده از android:windowSoftInputMode صفحه کلید نرم را نشان داد.
    • برنامه شما SHOW_IMPLICIT به showSoftInput() ارسال کرد.

به طور معمول، hideSoftInputFromWindow() صفحه‌کلید نرم را بدون توجه به اینکه چگونه درخواست شده است، پنهان می‌کند، اما با HIDE_IMPLICIT_ONLY می‌توان آن را فقط به رد کردن یک صفحه‌کلید نرم‌افزاری که به طور ضمنی درخواست شده محدود کرد.

نمایش دیالوگ یا نمای همپوشانی در بالای صفحه کلید نرم

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

برنامه شما چند گزینه دارد که در بخش های زیر توضیح داده می شود.

به طور خلاصه، مطمئن شوید که پرچم‌های پنجره صفحه‌کلید نرم را که پنجره را هدف قرار می‌دهند به‌طور صحیح مدیریت کنید تا انتظارات زیر را در مورد نظم دهی عمودی (لایه z) برآورده کند:

  • بدون پرچم (مورد معمولی): پشت لایه صفحه کلید نرم و می تواند متن را دریافت کند.
  • FLAG_NOT_FOCUSABLE : در بالای لایه صفحه کلید نرم، اما نمی تواند متن را دریافت کند.
  • FLAG_ALT_FOCUSABLE_IM : در بالای لایه صفحه‌کلید نرم، می‌توان فوکوس کرد، اما به صفحه‌کلید نرم متصل نیست. همچنین همه نماهای زیر آن را از اتصال به صفحه کلید نرم مسدود می کند. این برای نمایش گفتگوی برنامه ای که از ورودی متن بالای لایه صفحه کلید نرم استفاده نمی کند، مفید است.
  • FLAG_NOT_FOCUSABLE و FLAG_ALT_FOCUSABLE_IM : پشت لایه صفحه کلید نرم، اما نمی‌توانید متن را دریافت کنید.
  • FLAG_NOT_FOCUSABLE و FLAG_NOT_TOUCH_MODAL : در بالای صفحه‌کلید نرم، و اجازه دهید رویدادهای لمسی از طریق پنجره روی صفحه‌کلید نرم عبور کنند.

یک دیالوگ ایجاد کنید

از پرچم پنجره گفتگوی FLAG_ALT_FOCUSABLE_IM استفاده کنید تا گفتگو را در بالای صفحه کلید نرم نگه دارید و از تمرکز صفحه کلید نرم جلوگیری کنید:

کاتلین

val content = TextView(this)
content.text = "Non-editable dialog on top of soft keyboard"
content.gravity = Gravity.CENTER
val builder = AlertDialog.Builder(this)
  .setTitle("Soft keyboard layering demo")
  .setView(content)
mDialog = builder.create()
mDialog!!.window!!
  .addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
mDialog!!.show()

جاوا

TextView content = new TextView(this);
content.setText("Non-editable dialog on top of soft keyboard");
content.setGravity(Gravity.CENTER);
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
    .setTitle("Soft keyboard layering demo")
    .setView(content);
mDialog = builder.create();
mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
mDialog.show();

یک نمای همپوشانی ایجاد کنید

یک نمای همپوشانی ایجاد کنید که نوع پنجره TYPE_APPLICATION_OVERLAY و پرچم پنجره FLAG_ALT_FOCUSABLE_IM را توسط فعالیت هدفمند صفحه کلید نرم افزاری مشخص می کند.

کاتلین

val params = WindowManager.LayoutParams(
  width,  /* Overlay window width */
  height,  /* Overlay window height */
  WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */
  WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */
    or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,  /* Allow touch event send to soft keyboard behind the overlay */
  PixelFormat.TRANSLUCENT
)
params.title = "Overlay window"
mOverlayView!!.layoutParams = params
windowManager.addView(mOverlayView, params)

جاوا

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    width, /* Overlay window width */
    height, /* Overlay window height */
    TYPE_APPLICATION, /* Overlay window type */
    FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */
        | FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */
    PixelFormat.TRANSLUCENT);
params.setTitle("Overlay window");
mOverlayView.setLayoutParams(params);
getWindowManager().addView(mOverlayView, params);

یک دیالوگ یا نمای زیر صفحه‌کلید نرم‌افزار نمایش داده شود

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

  • در زیر صفحه‌کلید نرم درخواست‌شده توسط یک فعالیت ویرایشگر ظاهر می‌شود، به‌گونه‌ای که تحت تأثیر ورودی متن قرار نمی‌گیرد.
  • از تغییرات در اندازه ورودی صفحه کلید نرم افزاری برای تنظیم طرح گفتگو یا پنجره آگاه است.

در این صورت اپلیکیشن شما چندین گزینه دارد. بخش های زیر این گزینه ها را توضیح می دهند.

یک دیالوگ ایجاد کنید

با تنظیم پرچم پنجره FLAG_NOT_FOCUSABLE و پرچم پنجره FLAG_ALT_FOCUSABLE_IM یک گفتگو ایجاد کنید:

کاتلین

val content = TextView(this)
content.text = "Non-editable dialog behind soft keyboard"
content.gravity = Gravity.CENTER
val builder = AlertDialog.Builder(this)
  .setTitle("Soft keyboard layering demo")
  .setView(content)
mDialog = builder.create()
mDialog!!.window!!
  .addFlags(FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM)
mDialog!!.show()

جاوا

TextView content = new TextView(this);
content.setText("Non-editable dialog behind soft keyboard");
content.setGravity(Gravity.CENTER);
final AlertDialog.Builder builder = new AlertDialog.Builder(this)
    .setTitle("Soft keyboard layering demo")
    .setView(content);

mDialog = builder.create();
mDialog.getWindow()
    .addFlags(FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
mDialog.show();

یک نمای همپوشانی ایجاد کنید

با تنظیم پرچم پنجره FLAG_NOT_FOCUSABLE و پرچم پنجره FLAG_ALT_FOCUSABLE_IM یک نمای همپوشانی ایجاد کنید:

کاتلین

val params = WindowManager.LayoutParams(
  width,  /* Overlay window width */
  height,  /* Overlay window height */
  WindowManager.LayoutParams.TYPE_APPLICATION,  /* Overlay window type */
  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
      or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
  PixelFormat.TRANSLUCENT
)
params.title = "Overlay window"
mOverlayView!!.layoutParams = params
windowManager.addView(mOverlayView, params)

جاوا

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    width, /* Overlay window width */
    height, /* Overlay window height */
    TYPE_APPLICATION, /* Overlay window type */
    FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM,
    PixelFormat.TRANSLUCENT);
params.setTitle("Overlay window");
mOverlayView.setLayoutParams(params);
getWindowManager().addView(mOverlayView, params);