5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Android】Android 11から始めるIME Transitions

Posted at

IME Transitionsとは

Android 11 DP2から追加されたWindowInsets APIの一つです。
https://android-developers.googleblog.com/2020/03/android-11-developer-preview-2.html

ime_transition.gif

さっくり作ってみた

MainActivity.kt
import android.graphics.Insets
import android.os.Bundle
import android.view.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.updateLayoutParams
import androidx.core.view.updateMargins
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

    private val spacing36 by lazy {
        applicationContext.resources.getDimensionPixelOffset(R.dimen.spacing_36)
    }

    private val spacing16 by lazy {
        applicationContext.resources.getDimensionPixelOffset(R.dimen.spacing_16)
    }

    private val listener = object: WindowInsetsAnimationControlListener {
        override fun onCancelled() {
            animationController = null
            isFirst = true
        }

        override fun onReady(controller: WindowInsetsAnimationController, types: Int) {
            animationController = controller
        }
    }

    private var animationController: WindowInsetsAnimationController? = null

    private var isFirst = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        window.setDecorFitsSystemWindows(false)
        
        val callback = object: WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
            override fun onProgress(
                insets: WindowInsets,
                animations: MutableList<WindowInsetsAnimation>
            ): WindowInsets {
                text_input_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                    updateMargins(bottom = insets.getInsets(WindowInsets.Type.ime()).bottom + spacing16)
                }
                return insets
            }
        }
        text_input_layout.setWindowInsetsAnimationCallback(callback)

        scroll_view.setOnScrollChangeListener { view, x, y, oldX, oldY ->
            if (isFirst && y != 0) {
                isFirst = false
                text_input_layout.windowInsetsController?.controlWindowInsetsAnimation(
                    WindowInsets.Type.ime(),
                    -1,
                    null,
                    listener
                )
            }
            animationController?.setInsetsAndAlpha(Insets.of(0, 0, 0, scroll_view.scrollY - spacing36), 1f, 0f)
        }
    }
}

レイアウトファイルはScrollViewのなかにTextInputLayoutを追加すれば動く。

所感

その他にも、inputLayout.windowInsetsController.hide() or show()でキーボードの表示切り替えができます。
また、サンプルコードではTextInputLayoutにFocusが当たってるときと当たっていない時の制御を入れてないので、そこらへんの実装をちゃんとすればより良いUIになりそうです。

※DP2のため今後変更の可能性があります。

参考

https://android-developers.googleblog.com/2020/03/android-11-developer-preview-2.html
https://developer.android.com/reference/kotlin/android/view/WindowInsetsAnimation.Callback
https://developer.android.com/reference/android/view/WindowInsetsAnimationController

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?