باستخدام WindowInsetsCompat
،
يمكن لتطبيقك الاستعلام عن لوحة المفاتيح على الشاشة (المعروفة أيضًا باسم
IME) والتحكّم فيها على نحو مشابه
لطريقة تفاعله مع أشرطة النظام. يمكن لتطبيقك أيضًا استخدام رمز
WindowInsetsAnimationCompat
لإنشاء انتقالات سلسة عند فتح لوحة المفاتيح أو إغلاقها.
المتطلّبات الأساسية
قبل ضبط عناصر التحكّم والرسوم المتحركة للوحة المفاتيح، اضبط تطبيقك على العرض من الحافة إلى الحافة. يتيح ذلك للتطبيق التعامل مع أجزاء نافذة النظام المضمّنة، مثل أشرطة النظام ولوحة المفاتيح على الشاشة.
التحقّق من مستوى ظهور برنامج لوحة المفاتيح
استخدِم WindowInsets
للتحقّق من مستوى ظهور شاشة keyboard.
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 من واجهة برمجة التطبيقات)، حيث يتم فجأة التمرير إلى حقل النص ومحتوى التطبيق بدلاً من مزامنته مع التمويه المتحرك للوحة المفاتيح، وهو سلوك قد يكون مزعجًا من الناحية المرئية.
في الإصدار 11 من نظام Android (المستوى 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
:
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
:
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
:
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.