Вычисление adjustPan

#android #keyboard

#Android #клавиатура

Вопрос:

У меня есть представление в верхней части экрана, которое я хочу, чтобы оно всегда отображалось (на каждом устройстве, даже если открыта клавиатура). Проблема в том, что в середине экрана у меня есть EditText. На некоторых устройствах, если редактируемый текст получает фокус, клавиатура открывается и макет перемещается вверх. Я не хочу использовать adjustResize, который приведет к растягиванию фонового изображения. Можно ли узнать, был ли перемещен макет или нет из-за открытия клавиатуры? Кроме того, как было рассчитано это движение вверх? Я думаю о том, чтобы изменить вид, когда это необходимо

-Первая попытка решить проблему: я попробовал макет координатора. Я не нашел поведения, чтобы делать то, что я хочу, поэтому я попытался реализовать свое собственное поведение. Я добавил вид пространства в нижней части макета, и всякий раз, когда этот вид менял свое положение, я пытался перевести вид сверху вниз. Но даже если layoutDependsOn() возвращает true, onDependentViewChanged() не вызывается для вычисления перевода.

-Вторая попытка решить проблему: я снова добавил представление пространства в нижней части макета. Кроме того, я добавил OnGlobalLayoutListener, чтобы отслеживать, была ли открыта клавиатура. Если это так, я попытался вычислить позицию space view и сравнить ее с предыдущей позицией, чтобы переместить вид сверху вниз.

-Третья попытка заключалась в использовании adjustNothing и самостоятельной передаче переводов представлений, которые необходимо переместить на клавиатуре open. Это была единственная попытка, которая дала мне некоторые результаты, но кажется ошибочной, и в будущем, я уверен, это вызовет гораздо больше проблем, чем решит.

Кроме того, я обнаружил, что x, y, translationX, translationY не изменяются в adjustPan. Единственный способ вычислить правильную позицию — использовать getLocationOnScreen(). Но это возможно после того, как представление было выложено. Можем ли мы вычислить это до того, как будет выложено представление?

Ответ №1:

Для дальнейшего использования, чтобы вычислить пиксели восходящего перевода в режиме adjustPan, вы должны выполнить что-то вроде следующего кода. В принципе, в adjustPan мы нажимаем столько, сколько необходимо, на макет, чтобы сделать сфокусированный текст редактирования полностью видимым.

 val rect = Rect()
constraintLayout.getWindowVisibleDisplayFrame(rect)
val editTextGlobalRect = Rect()
view.getGlobalVisibleRect(editTextGlobalRect)

//if it is true the editText will be hidden so the layout will be moved upwards due to adjust pan
val translation = if (editTextGlobalRect.bottom > visibleArea.bottom) {
    //Calculate how much the layout is going to be pushed
    editTextGlobalRect.bottom - visibleArea.bottom.toFloat()
} else {
    0f
}
  

Кроме того, если вы хотите вычислить новое положение вида, чтобы оставаться в том же положении экрана, вы должны сделать что-то подобное:

 val stationaryViewGlobalRect = Rect()
stationaryView.getGlobalVisibleRect(stationaryViewGlobalRect)

stationaryView.y = when {
    translation <= stationaryViewGlobalRect.top -> {
        //Stationary view is not hidden at all but it was moved upwards
        stationaryViewGlobalRect.top - translation   resources.getDimension(R.dimen.stationary_view_margin_top)
    }
    translation <= stationaryViewGlobalRect.bottom -> {
        //Stationary view is not fully hidden
        translation   (stationaryViewGlobalRect.bottom - translation)
    }
    else -> translation   stationaryViewGlobalRect.top //Stationary view is fully hidden
}
  

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

1. Вышесказанное имеет смысл, но как получены значения для visibleArea ?