WindowInsetsCompat
का इस्तेमाल करके, आपका ऐप्लिकेशन ऑन-स्क्रीन कीबोर्ड (इसे आईएमई भी कहा जाता है) से उसी तरह क्वेरी कर सकता है और उसे कंट्रोल कर सकता है जिस तरह वह सिस्टम बार से इंटरैक्ट करता है. आपका ऐप्लिकेशन, सॉफ़्टवेयर कीबोर्ड के खुलने या बंद होने पर, आसानी से ट्रांज़िशन बनाने के लिए भी 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; });
सॉफ़्टवेयर कीबोर्ड के साथ ऐनिमेशन सिंक करना
जब कोई उपयोगकर्ता टेक्स्ट इनपुट फ़ील्ड पर टैप करता है, तो कीबोर्ड स्क्रीन के सबसे नीचे से स्लाइड करके अपनी जगह पर आ जाता है. इसका उदाहरण यहां दिया गया है:
दूसरे चित्र में, "अनसिंक्रोनाइज़ किया गया" लेबल वाले उदाहरण में, Android 10 (एपीआई लेवल 29) में डिफ़ॉल्ट व्यवहार दिखाया गया है. इसमें, ऐप्लिकेशन का टेक्स्ट फ़ील्ड और कॉन्टेंट, कीबोर्ड के ऐनिमेशन के साथ सिंक होने के बजाय, अपनी जगह पर स्नैप हो जाता है. यह ऐसा व्यवहार है जो दिखने में खराब लग सकता है.
Android 11 (एपीआई लेवल 30) और इसके बाद के वर्शन में, ऐप्लिकेशन के ट्रांज़िशन को स्क्रीन के सबसे नीचे से ऊपर और नीचे की ओर स्लाइड करने वाले कीबोर्ड के साथ सिंक करने के लिए,
WindowInsetsAnimationCompat
का इस्तेमाल किया जा सकता है. यह सिलसिलेवार तरीके से दिखता है, जैसा कि दूसरी इमेज में "सिंक किया गया" लेबल वाले उदाहरण में दिखाया गया है.
कीबोर्ड ऐनिमेशन के साथ सिंक किए जाने वाले व्यू के साथ, 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
को तब कॉल किया जाता है, जब इनसेट ऐनिमेशन शुरू हो रहा हो और ऐनिमेशन की वजह से व्यू को फिर से व्यवस्थित करने से पहले. इसका इस्तेमाल, शुरू की स्थिति को सेव करने के लिए किया जा सकता है. इस मामले में, यह व्यू का सबसे नीचे वाला निर्देशांक है.

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
को तब कॉल किया जाता है, जब इनसेट ऐनिमेशन शुरू होता है. इसका इस्तेमाल करके, सभी व्यू प्रॉपर्टी को लेआउट में हुए बदलावों की आखिरी स्थिति पर सेट किया जा सकता है. अगर आपने किसी भी व्यू के लिए 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
को तब कॉल किया जाता है, जब ऐनिमेशन चलाने के दौरान इनसेट बदलते हैं, ताकि आप इसे बदल सकें और कीबोर्ड ऐनिमेशन के दौरान हर फ़्रेम पर सूचना पा सकें. व्यू की प्रॉपर्टी अपडेट करें, ताकि व्यू, कीबोर्ड के साथ सिंक करके ऐनिमेट हो.
इस समय, लेआउट में किए गए सभी बदलाव पूरे हो जाते हैं. उदाहरण के लिए, अगर व्यू को शिफ़्ट करने के लिए 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
को बदलने का विकल्प भी है. ऐनिमेशन खत्म होने के बाद, इस तरीके को कॉल किया जाता है. यह समय, कुछ समय के लिए किए गए बदलावों को हटाने का अच्छा समय है.
अन्य संसाधन
- GitHub पर WindowInsetsAnimation.