การใช้ 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 (ระดับ API 29) ซึ่งช่องข้อความและเนื้อหาของแอปจะเลื่อนเข้าที่แทนที่จะซิงค์กับภาพเคลื่อนไหวของแป้นพิมพ์ ซึ่งอาจทำให้เกิดการเปลี่ยนแปลงที่เห็นได้ชัดเจน
ใน Android 11 (ระดับ API 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