باستخدام WindowInsetsCompat،
يمكن لتطبيقك طلب لوحة المفاتيح على الشاشة (المعروفة أيضًا باسم
IME) والتحكّم فيها بطريقة مشابهة لـ
طريقة تفاعله مع أشرطة النظام. يمكن لتطبيقك أيضًا استخدام
WindowInsetsAnimationCompat
لإنشاء انتقالات سلسة عند فتح لوحة مفاتيح افتراضية أو إغلاقها.
المتطلبات الأساسية
قبل إعداد عناصر التحكّم والصورة المتحركة للوحة المفاتيح الافتراضية، عليك ضبط تطبيقك لعرض المحتوى من الحافة إلى الحافة. يتيح ذلك للتطبيق التعامل مع مساحات العرض الداخلية لنافذة النظام، مثل أشرطة النظام ولوحة المفاتيح على الشاشة.
التحقّق من ظهور لوحة المفاتيح البرمجية
استخدِم WindowInsets للتحقّق من ظهور لوحة المفاتيح البرمجية.
Kotlin
val insets = ViewCompat.getRootWindowInsets(view) ?: return val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
Java
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(view); boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
بدلاً من ذلك، يمكنك استخدام
ViewCompat.setOnApplyWindowInsetsListener
لمراقبة التغييرات في ظهور لوحة المفاتيح البرمجية.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets -> val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom insets }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> { boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; return insets; });
مزامنة الصورة المتحركة مع لوحة المفاتيح الافتراضية
عندما ينقر المستخدم على حقل إدخال نص، تنزلق لوحة المفاتيح إلى مكانها من أسفل الشاشة، كما هو موضّح في المثال التالي:
يعرض المثال الذي يحمل التصنيف "غير متزامنة" في الشكل 2 السلوك التلقائي في Android 10 (مستوى واجهة برمجة التطبيقات 29)، حيث يتم تثبيت حقل النص ومحتوى التطبيق في مكانهما بدلاً من مزامنتهما مع الصورة المتحركة للوحة المفاتيح، وهو سلوك قد يكون غير مريح بصريًا.
في Android 11 (مستوى واجهة برمجة التطبيقات 30) والإصدارات الأحدث، يمكنك استخدام
WindowInsetsAnimationCompatلمزامنة انتقال التطبيق مع انزلاق لوحة المفاتيح للأعلى والأسفل من أسفل الشاشة. يبدو هذا الانتقال أكثر سلاسة، كما هو موضّح في المثال الذي يحمل التصنيف "متزامنة" في الشكل 2.
اضبط
WindowInsetsAnimationCompat.Callback
مع طريقة العرض التي ستتم مزامنتها مع الصورة المتحركة للوحة المفاتيح.
Kotlin
ViewCompat.setWindowInsetsAnimationCallback( view, object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) { // Override methods. } )
Java
ViewCompat.setWindowInsetsAnimationCallback( view, new WindowInsetsAnimationCompat.Callback( WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP ) { // Override methods. });
هناك عدة طرق يجب إلغاؤها في WindowInsetsAnimationCompat.Callback,
وهي
onPrepare(),
onStart(),
onProgress(),
و
onEnd().
ابدأ باستدعاء onPrepare() قبل إجراء أي تغييرات في التصميم.
يتم استدعاء onPrepare عند بدء صورة متحركة لمساحات العرض الداخلية وقبل إعادة ترتيب طرق العرض بسبب صورة متحركة. يمكنك استخدامها لحفظ حالة البدء، وهي في هذه الحالة الإحداثي السفلي لطريقة العرض.
onPrepare() لتسجيل حالة البدء
يعرض المقتطف التالي نموذجًا لاستدعاء onPrepare:
Kotlin
var startBottom = 0f override fun onPrepare( animation: WindowInsetsAnimationCompat ) { startBottom = view.bottom.toFloat() }
Java
float startBottom; @Override public void onPrepare( @NonNull WindowInsetsAnimationCompat animation ) { startBottom = view.getBottom(); }
يتم استدعاء onStart عند بدء صورة متحركة لمساحات العرض الداخلية. يمكنك استخدامها لضبط جميع خصائص طريقة العرض على حالة الانتهاء من تغييرات التصميم. إذا تم ضبط معاودة الاتصال OnApplyWindowInsetsListener على أي من طرق العرض، يتم استدعاؤها في هذه المرحلة. هذا هو الوقت المناسب لحفظ حالة الانتهاء من خصائص طريقة العرض.
onStart() لتسجيل
حالة الانتهاء.
يعرض المقتطف التالي نموذجًا لاستدعاء onStart:
Kotlin
var endBottom = 0f override fun onStart( animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat ): WindowInsetsAnimationCompat.BoundsCompat { // Record the position of the view after the IME transition. endBottom = view.bottom.toFloat() return bounds }
Java
float endBottom; @NonNull @Override public WindowInsetsAnimationCompat.BoundsCompat onStart( @NonNull WindowInsetsAnimationCompat animation, @NonNull WindowInsetsAnimationCompat.BoundsCompat bounds ) { endBottom = view.getBottom(); return bounds; }
يتم استدعاء onProgress عند تغيير مساحات العرض الداخلية كجزء من تشغيل صورة متحركة، لذا يمكنك إلغاؤها وتلقّي إشعار في كل إطار أثناء الصورة المتحركة للوحة المفاتيح. عدِّل خصائص طريقة العرض بحيث تتحرّك طريقة العرض بشكل متزامن مع لوحة المفاتيح.
في هذه المرحلة، تكون جميع تغييرات التصميم قد اكتملت. على سبيل المثال، إذا كنت تستخدم View.translationY لنقل طريقة العرض، تنخفض القيمة تدريجيًا لكل استدعاء لهذه الطريقة وتصل في النهاية إلى 0 في موضع التصميم الأصلي.
onProgress() لمزامنة الصور المتحركة
يعرض المقتطف التالي نموذجًا لاستدعاء onProgress:
Kotlin
override fun onProgress( insets: WindowInsetsCompat, runningAnimations: MutableList<WindowInsetsAnimationCompat> ): WindowInsetsCompat { // Find an IME animation. val imeAnimation = runningAnimations.find { it.typeMask and WindowInsetsCompat.Type.ime() != 0 } ?: return insets // Offset the view based on the interpolated fraction of the IME animation. view.translationY = (startBottom - endBottom) * (1 - imeAnimation.interpolatedFraction) return insets }
Java
@NonNull @Override public WindowInsetsCompat onProgress( @NonNull WindowInsetsCompat insets, @NonNull List<WindowInsetsAnimationCompat> runningAnimations ) { // Find an IME animation. WindowInsetsAnimationCompat imeAnimation = null; for (WindowInsetsAnimationCompat animation : runningAnimations) { if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) { imeAnimation = animation; break; } } if (imeAnimation != null) { // Offset the view based on the interpolated fraction of the IME animation. view.setTranslationY((startBottom - endBottom) * (1 - imeAnimation.getInterpolatedFraction())); } return insets; }
يمكنك اختياريًا إلغاء onEnd. يتم استدعاء هذه الطريقة بعد انتهاء الصورة المتحركة. هذا هو الوقت المناسب لإزالة أي تغييرات مؤقتة.
مراجع إضافية
- WindowInsetsAnimation على GitHub.