Android: обнаружение открытой клавиатуры, не работает onApplyWindowListener

#android #android-layout #kotlin

#Android #android-layout #kotlin

Вопрос:

Я пытаюсь скрыть одну конкретную кнопку в нижней части моего макета при открытии клавиатуры, чтобы предоставить пользователю больше возможностей для просмотра.

С выпуском androidx.core:core-ktx:1.5.0-alpha02 Google (наконец) добавлен метод с именем insets.isVisible(WindowInsetsCompat.Type.ime()) , который возвращает логическое значение независимо от того, открыта клавиатура или нажата.

Я использую базовый класс EmailFragment , где я устанавливаю функцию для достижения вышеуказанной функциональности. Моя проблема в том, что мой ViewCompat.setOnApplyWindowInsetsListener(view) никогда не вызывается (без тостов и т.д.).

Я также пытался установить ViewCompat.setOnApplyWindowInsetsListener(view) непосредственно в используемых фрагментах, но это ничего не изменило.

Мой минимальный API равен 21, в моем AndroidManifest.XML у меня есть android:windowSoftInputMode = adjustResize

Код

 abstract class EmailFragment<out T: ViewDataBinding>(
    layout: Int,
    // ... some other stuff that is not necessary for the question
) : BaseFragment<T>(layout) {
    // ... some other stuff that is not necesarry for the question

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        hideButton(view)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    
    private fun hideButton(view: View) {
        ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
            val isKeyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
            if (isKeyboardVisible) {
                btn.visibility = View.GONE
                Toast.makeText(requireContext(), "KEYBOARD OPEN", Toast.LENGTH_SHORT).show()
            } else {
                btn.visibility = View.VISIBLE
                Toast.makeText(requireContext(), "KEYBOARD CLOSED", Toast.LENGTH_SHORT).show()
            }

            // Return the insets to keep going down this event to the view hierarchy
            insets
        }
    }
}
  

Фрагмент, который наследуется от EmailFragment (один из пяти)

 class CalibrateRepairMessageFragment(
    //... some other stuff that is not necessary for this question
) : EmailFragment<FragmentCalibrateRepairMessageBinding>(
    R.layout.fragment_calibrate_repair_message,
    //... some other stuff that is not necessary for this question
) {
    //... some other stuff that is not necessary for this question

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //... some other stuff that is not necessary for this question
    }
  

Скриншот 1 (подвергнут цензуре)

введите описание изображения здесь

Скриншот 2, не работает (подвергнут цензуре)

введите описание изображения здесь

Я знаю, что использование android:windowSoftInputMode = adjustPen делает мою кнопку «невидимой», но тогда я больше не могу прокручивать, очень грустно..

Другим решением может быть то, что клавиатура просто перекрывает кнопку, но я понятия не имею, как это сделать…

Я ценю любую помощь, спасибо.

Комментарии:

1. Какую версию Android вы используете для тестирования?

2. @PankajKumar Я тестирую его с помощью эмулятора, который работает на Android 10

3. Вы тестировали это на Android 11? И эта функция еще не выпущена, поэтому я бы рекомендовал вам подождать некоторое время, а затем использовать старый способ.

4. @Andrew вы нашли решение для этого? Я сталкиваюсь с той же проблемой?

5. @dakshbhatt21 К сожалению, нет, как было сказано выше, эта функция либо 1. Не работает вообще (потому что альфа), либо 2. работает только для устройств с Android 11. Я попытаюсь разобраться в этом позже, но у меня нет никакой надежды, что это когда-нибудь сработает..

Ответ №1:

Я смог заставить это работать с помощью:

  1. Добавление android:windowSoftInputMode="adjustResize" в Activity тег в манифесте
  2. Настройка OnApplyWindowInsetsListener включена window.decorView .

Однако это имело неприятные побочные эффекты в строке состояния, что означает, что комментарий OP («У меня нет надежды, что это когда-нибудь сработает»), вероятно, точен. Надеюсь, это сработает, когда он выйдет из альфа-версии и бета-версии.

Комментарии:

1. Я получил эту работу, следуя вашим рекомендациям, но я не знаю, как обнулить прослушиватель в kotlin. Мне нужно объявить переменную вверху как частное оформление переменной: ?? Я не уверен, поэтому я могу получить к нему доступ и обнулить его в onDestroyView, иначе это приведет к нулевому значению при переходе к другому фрагменту.