با استفاده از 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; });
همگامسازی انیمیشن با صفحهکلید نرمافزار
همانطور که در مثال زیر نشان داده شده است، کاربری که روی یک فیلد ورودی متن ضربه میزند، باعث میشود صفحهکلید از پایین صفحه به جای خود بلغزد:
- مثالی که در شکل ۲ با عنوان «غیرهمگامسازیشده» مشخص شده است، رفتار پیشفرض در اندروید ۱۰ (سطح API ۲۹) را نشان میدهد که در آن فیلد متنی و محتوای برنامه به جای همگامسازی با انیمیشن صفحهکلید، در جای خود قرار میگیرند - رفتاری که میتواند از نظر بصری نامطلوب باشد. 
- در اندروید ۱۱ (سطح API 30) و بالاتر، میتوانید از - WindowInsetsAnimationCompatبرای همگامسازی انتقال برنامه با صفحهکلید که از پایین صفحه به بالا و پایین میلغزد، استفاده کنید. این روش، همانطور که در مثال با برچسب "Synchronized" در شکل ۲ نشان داده شده است، روانتر به نظر میرسد.
 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. });
 چندین متد برای override کردن در WindowInsetsAnimationCompat.Callback وجود دارد، که عبارتند از onPrepare() ، onStart() ، onProgress() و onEnd() . قبل از هرگونه تغییر در طرحبندی، با فراخوانی onPrepare() شروع کنید.
 onPrepare زمانی فراخوانی میشود که یک انیمیشن insets شروع میشود و قبل از اینکه نماها به دلیل یک انیمیشن دوباره چیدمان شوند. میتوانید از آن برای ذخیره حالت شروع استفاده کنید، که در این مورد مختصات پایین نما است. 

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(); }
 onStart زمانی فراخوانی میشود که یک انیمیشن insets شروع میشود. میتوانید از آن برای تنظیم تمام ویژگیهای نما در حالت پایانی تغییرات طرحبندی استفاده کنید. اگر یک فراخوانی برگشتی OnApplyWindowInsetsListener برای هر یک از نماها تنظیم کردهاید، در این مرحله از قبل فراخوانی شده است. اکنون زمان مناسبی برای ذخیره حالت پایانی ویژگیهای نما است. 

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 زمانی فراخوانی میشود که مقادیر insets به عنوان بخشی از اجرای یک انیمیشن تغییر کنند، بنابراین میتوانید آن را لغو کنید و در طول انیمیشن صفحه کلید، در هر فریم از آن مطلع شوید. ویژگیهای نما را بهروزرسانی کنید تا نما با صفحه کلید هماهنگ شود.
 تمام تغییرات طرحبندی در این مرحله کامل شدهاند. برای مثال، اگر از 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 override کنید. این متد پس از پایان انیمیشن فراخوانی میشود. این زمان مناسبی برای پاک کردن هرگونه تغییر موقت است.
منابع اضافی
- انیمیشن پنجرهها (WinsetsAnimation) در گیتهاب.
 
  