با استفاده از WindowInsetsCompat
، برنامه شما میتواند صفحهکلید روی صفحه (که IME نیز نامیده میشود) پرس و جو و کنترل کند، شبیه به نحوه تعامل آن با نوارهای سیستم. برنامه شما همچنین میتواند از WindowInsetsAnimationCompat
برای ایجاد انتقال بدون درز هنگام باز یا بسته شدن صفحهکلید نرمافزار استفاده کند.
پیش نیازها
قبل از تنظیم کنترل و انیمیشن برای صفحه کلید نرم افزار، برنامه خود را برای نمایش لبه به لبه پیکربندی کنید. این به آن اجازه میدهد تا با ورودیهای پنجرهی سیستم مانند نوارهای سیستم و صفحهکلید روی صفحه کار کند.
قابلیت مشاهده نرم افزار صفحه کلید را بررسی کنید
از WindowInsets
برای بررسی قابلیت مشاهده صفحه کلید نرم افزار استفاده کنید.
کاتلین
val insets = ViewCompat.getRootWindowInsets(view) ?: return val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
جاوا
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(view); boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
از طرف دیگر، می توانید از ViewCompat.setOnApplyWindowInsetsListener
برای مشاهده تغییرات روی صفحه کلید نرم افزار استفاده کنید.
کاتلین
ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets -> val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom insets }
جاوا
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> { boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; return insets; });
همگام سازی انیمیشن با صفحه کلید نرم افزار
ضربه زدن کاربر به فیلد ورودی متن باعث می شود صفحه کلید از پایین صفحه به جای خود بلغزد، همانطور که در مثال زیر نشان داده شده است:
مثالی که در شکل 2 با عنوان "Unsynchronized" نامگذاری شده است، رفتار پیشفرض اندروید 10 (سطح API 29) را نشان میدهد که در آن قسمت متن و محتوای برنامه به جای همگامسازی با انیمیشن صفحهکلید در جای خود میچسبد - رفتاری که میتواند از نظر بصری ناخوشایند باشد.
در اندروید 11 (سطح API 30) و بالاتر، میتوانید از
WindowInsetsAnimationCompat
برای همگامسازی انتقال برنامه با صفحهکلید که از پایین صفحه به بالا و پایین میلغزد، استفاده کنید. همانطور که در مثال با عنوان "Synchronized" در شکل 2 نشان داده شده است، این نرم افزار به نظر می رسد.
WindowInsetsAnimationCompat.Callback
را با نمای همگام سازی با انیمیشن صفحه کلید پیکربندی کنید.
کاتلین
ViewCompat.setWindowInsetsAnimationCallback( view, object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) { // Override methods. } )
جاوا
ViewCompat.setWindowInsetsAnimationCallback( view, new WindowInsetsAnimationCompat.Callback( WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP ) { // Override methods. });
چندین روش برای لغو در WindowInsetsAnimationCompat.Callback
وجود دارد که عبارتند از onPrepare()
, onStart()
, onProgress()
و onEnd()
. با فراخوانی onPrepare()
قبل از هر یک از تغییرات طرح شروع کنید.
onPrepare
زمانی فراخوانی می شود که یک انیمیشن insets شروع می شود و قبل از اینکه نماها به دلیل یک انیمیشن دوباره نمایش داده شوند. می توانید از آن برای ذخیره حالت شروع استفاده کنید که در این حالت مختصات پایینی نما است.
![تصویری که مختصات پایین حالت شروع نمای ریشه را نشان می دهد.](https://developer.android.com/static/images/guide/navigation/software-keyboard-3.png?hl=fa)
onPrepare()
برای ثبت وضعیت شروع. قطعه زیر یک نمونه تماس با onPrepare
را نشان می دهد:
کاتلین
var startBottom = 0f override fun onPrepare( animation: WindowInsetsAnimationCompat ) { startBottom = view.bottom.toFloat() }
جاوا
float startBottom; @Override public void onPrepare( @NonNull WindowInsetsAnimationCompat animation ) { startBottom = view.getBottom(); }
هنگام شروع انیمیشن insets onStart
فراخوانی می شود. می توانید از آن برای تنظیم تمام ویژگی های view در حالت پایانی تغییرات طرح بندی استفاده کنید. اگر پاسخ تماس OnApplyWindowInsetsListener
روی هر یک از نماها تنظیم شده باشد، قبلاً در این مرحله فراخوانی شده است. این زمان خوبی برای ذخیره وضعیت پایانی خصوصیات view است.
![تصویری که مختصات پایین حالت پایانی نما را نشان می دهد](https://developer.android.com/static/images/guide/navigation/software-keyboard-4.png?hl=fa)
onStart()
برای ثبت وضعیت پایانی. قطعه زیر یک تماس نمونه با onStart
را نشان می دهد:
کاتلین
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 }
جاوا
float endBottom; @NonNull @Override public WindowInsetsAnimationCompat.BoundsCompat onStart( @NonNull WindowInsetsAnimationCompat animation, @NonNull WindowInsetsAnimationCompat.BoundsCompat bounds ) { endBottom = view.getBottom(); return bounds; }
onProgress
زمانی فراخوانی میشود که ورودیها به عنوان بخشی از اجرای یک انیمیشن تغییر میکنند، بنابراین میتوانید آن را لغو کنید و در طول انیمیشن صفحه کلید در هر فریم به شما اطلاع داده شود. ویژگی های view را به روز کنید تا نما در هماهنگی با صفحه کلید متحرک شود.
تمام تغییرات طرح در این مرحله کامل شده است. به عنوان مثال، اگر از View.translationY
برای جابجایی نما استفاده می کنید، مقدار به تدریج برای هر فراخوانی این روش کاهش می یابد و در نهایت به موقعیت طرح اولیه 0
می رسد.
onProgress()
برای همگام سازی انیمیشن ها. قطعه زیر یک تماس نمونه به onProgress
را نشان می دهد:
کاتلین
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 }
جاوا
@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.