Android イマーシブ ステータス バーの下に PreferenceFragment によってポップアップされる入力ダイアログ ボックスがキーボードの上向きの動きに追従できない問題の解決方法

背景の紹介

ステータスバーが埋まっていない場合、PreferenceFragmentCompatEditTextPreference がある場合、そのエントリをクリックすると呼び出される入力ダイアログ ボックスが上に移動します。キーボードを使用しますが、styles.xml に設定すると

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

つまり、ステータス バーまたはナビゲーション バーを埋め込んだ後、ダイアログ ボックスを呼び出すときに上に移動することはできません。

歴史の要約

これは 2013 年からの古いバグです1。Google が没入型ステータス バー機能を導入して以来、このバグは解決されていません。修復、 stackoverflow2 には、コントロールを手動で上に移動することで問題を大まかに解決する多くの投稿があります。

私の質問

これらの投稿のほとんどはカスタム ビューの EditText に関するものであるため、カスタマイズは比較的簡単です。この GitHub の回答が最適です。 , ほぼすべてのレイアウトに適応できますが、システムのパッケージ化では、このコードはキーボードが呼び出された後の高さの変化のみを検出でき、入力ボックスを自動的に上に移動することはできません。 PreferenceFragmentCompat

解決

上記の情報を総合し、PreferenceFragmentCompat の特性を組み合わせた後、最終的な解決策を作成しました。これは完璧な解決策ではないかもしれませんが、問題なく機能します。

package xxx.yyy.zzz

import android.animation.ObjectAnimator
import android.graphics.Rect
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window
import androidx.annotation.Keep
import androidx.preference.EditTextPreference
import androidx.preference.EditTextPreferenceDialogFragmentCompat
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import xxx.yyy.zzz.R
import java.lang.Thread.sleep

class SettingsFragment: PreferenceFragmentCompat() {
    
    
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    
    
        setPreferencesFromResource(R.xml.pref_setting, rootKey)
    }

    override fun onDisplayPreferenceDialog(preference: Preference) {
    
    
        if (preference is EditTextPreference) {
    
    
            Log.d("MySF", "preference is EditTextPreference")
            val f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.key)
            f.setTargetFragment(this, 0)
            f.show(parentFragmentManager, null)
            Thread {
    
    
                var diff = 0
                var cnt = 0
                while (diff == 0 && cnt++ < 20) {
    
    
                    sleep(50)
                    if (f.dialog == null) continue
                    val v = view?:return@Thread
                    // https://github.com/mikepenz/MaterialDrawer/blob/aa9136fb4f5b3a80460fe5f47213985026d20c88/library/src/main/java/com/mikepenz/materialdrawer/util/KeyboardUtil.java
                    val r = Rect()
                    //r will be populated with the coordinates of your view that area still visible.
                    v.getWindowVisibleDisplayFrame(r)
                    //get screen height and calculate the difference with the useable area from the r
                    val height = v.context.resources.displayMetrics.heightPixels
                    diff = height - r.bottom
                    Log.d("MySF", "diff: $diff")
                }
                Log.d("MySF", "diff out while: $diff")
                if (diff <= 0) return@Thread
                Log.d("MySF", "f.dialog is ${
      
      f.dialog}")
                f.activity?.runOnUiThread {
    
    
                    f.dialog?.window?.apply {
    
    
                        val attr = attributes
                        Log.d("MySF", "animate from ${
      
      attr.y} to ${
      
      attr.y-diff/2}")
                        ObjectAnimator.ofInt(WindowAttributeSetter(this), "y", attr.y, attr.y-diff/2).setDuration(233).start()
                    }
                }
            }.start()
            return
        }
        super.onDisplayPreferenceDialog(preference)
    }

    inner class WindowAttributeSetter(private val window: Window) {
    
    
        @Keep
        fun setY(y: Int) {
    
    
            val attr = window.attributes
            attr.y = y
            Log.d("MySF", "set y to $y")
            window.attributes = attr
        }
    }
}

  1. android:windowTranslucentStatus=true の場合、キーボードは画面のサイズを変更しません ↩︎

  2. android:windowTranslucentStatus=true の場合にキーボードが EditText を非表示にする ↩︎

おすすめ

転載: blog.csdn.net/u011570312/article/details/134201012