Как получить высоту каждой строки в тексте редактирования

Я хочу анимировать клавиатуру при добавлении или удалении новой строки, как это делает телеграмма. Я могу добавить анимацию следующим образом:

private void doAnimation(int linesCount, String s){
        Toast.makeText(this, "" + linesCount, Toast.LENGTH_SHORT).show();
        if (linesCount == 1){
            binding.message.getLayoutParams().height = defEditTextHeight;
            return;
        }
        if (linesCount < binding.message.getLineCount()) {
            ValueAnimator anim = ValueAnimator.ofInt(binding.message.getHeight(), binding.message.getHeight() + 60)
                    .setDuration(250);
            anim.addUpdateListener(animation -> {
                binding.message.getLayoutParams().height = (int) animation.getAnimatedValue();
                binding.message.requestLayout();
            });
            anim.start();
        }else if ( linesCount > binding.message.getLineCount()){
            ValueAnimator anim = ValueAnimator.ofInt(binding.message.getHeight(), binding.message.getHeight() - 60)
                    .setDuration(250);
            anim.addUpdateListener(animation -> {
                binding.message.getLayoutParams().height = (int) animation.getAnimatedValue();
                binding.message.requestLayout();
            });
            anim.start();
        }
    }

Но, как вы можете видеть, для анимации я добавляю случайное значение, например 60. Но это не надежно для всех устройств.

Итак, как я могу получить высоту каждой строки, чтобы добавить ее и получить хорошую анимацию?

Заранее спасибо ?

Захват высоты текста при добавлении каждой строки. Затем, когда добавляется или удаляется еще одна строка, разница между текущей высотой и последней высотой представляет собой величину увеличения или уменьшения. Нужно ли что-то более сложное, чем это?

Cheticamp 20.03.2022 14:22

@Cheticamp позвольте мне попробовать это. На самом деле метод getHeight() возвращает 0, а getLayoutParams().height дает -2. Я попробовал то, что вы сказали. Но это не работает

Sambhav. K 20.03.2022 14:34

Если getHeight() возвращает ноль, вам придется дождаться макета, чтобы получить измерение.

Cheticamp 20.03.2022 14:49

можете предоставить код?

Sambhav. K 20.03.2022 14:49

Чтобы дождаться завершения компоновки, взгляните на View.OnLayoutChangeListener или ViewTreeObserver.OnGlobalLayoutListener. Есть пример использования в Интернете.

Cheticamp 20.03.2022 14:54

Спасибо. Было бы здорово, если бы вы могли опубликовать это как ответ. я проверю это

Sambhav. K 20.03.2022 14:55
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Высота каждой строки Редактировать текст задается StaticLayout, созданным Редактировать текст.

// Get vertical padding of the EditText
int padding = binding.message.getPaddingTop() + binding.message.getPaddingBottom();

// Get the total height of the EditText
int totalHeight = binding.message.getLayout().getHeight() + padding;
// or
int totalHeight = binding.message.getHeight();

// Get the height that line i contributes to the EditText. 
int height = binding.message.getLayout().getLineBottom(i) - binding.message.getLayout().getLineTop(i);

Итак, ваши определения анимации будут выглядеть так:

int i = linesCount - 1;
int height = binding.message.getLayout().getLineBottom(i) - binding.message.getLayout().getLineTop(i);
ValueAnimator anim = ValueAnimator.ofInt(binding.message.getHeight(), binding.message.getHeight() + height)
                .setDuration(250);

Если вам нужно дождаться макета, вы можете использовать следующее:

binding.message.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
    // code here 
};

Итак, какой из них предпочтительнее? int totalHeight = binding.message.getLayout().getHeight() + padding; ИЛИ int totalHeight = binding.message.getHeight();

Sambhav. K 21.03.2022 16:26

Я бы предпочел int totalHeight = binding.message.getHeight();

Cheticamp 21.03.2022 16:33

в порядке. позвольте мне попробовать это

Sambhav. K 21.03.2022 16:35

когда нужно будет ждать макет? Я не понимаю и что мне делать в //code here?

Sambhav. K 21.03.2022 16:39

Если сумма 60 работает на вас, я бы просто взял binding.message.getLayout().getLineBottom(i) - binding.message.getLayout().getLineTop(i) в качестве замены. i будет ссылаться на только что добавленную или только что удаленную строку.

Cheticamp 21.03.2022 17:09

Другие вопросы по теме