Android requestlayout dont work

RequestLayout() improperly called #371

Comments

A-Lim commented Jul 21, 2016 •

I’ve got these warnings whenever the Tab Bar activity is launched.

Any idea on what might be the problem?

The text was updated successfully, but these errors were encountered:

jessexx commented Jul 21, 2016

I have the same issue, it doesn’t seem to be affecting performance in any way but it shows up in the logger. I’m attaching the BottomBar with five items that have Drawables for icons if that helps.

jchen236 commented Aug 1, 2016

I am also getting these warnings.

mdeyell commented Aug 16, 2016

I am also getting these, with 5 icons.

johncodeos commented Aug 18, 2016

REWKyleB commented Aug 22, 2016

firetrap commented Sep 1, 2016

+1 and the textView it’s being cut on every click

UmarBhutta commented Sep 19, 2016

+1 and text is not showing on Android L

a00909032 commented Sep 29, 2016 •

trying to figure this out too. any solution yet? bottom bar title doesnt show appear either.

Rikkokiri commented Dec 11, 2016

Yeah I have the same issue.

iRYO400 commented Jan 24, 2017

thumb up! Still in Ver. 2.1.1

strajky5 commented Jan 27, 2017

i have the same issue with ver. 2.1.1

Zoomagic commented Feb 1, 2017 •

+1 as mentioned by Firetrap the text may be to blame — the text in my project is getting halved after one click.

heitorpr commented Feb 8, 2017

+1 the same here with the same scenario. BottomBar with 5 itens all with icons and labels.

chaleao commented Feb 17, 2017 •

+1 on the version 2.1.1

burhanaksendir commented Feb 24, 2017

I have the same issue.

kandreadou commented Mar 27, 2017

Same issue here

yombunker commented Mar 27, 2017

is this happening on the latest version? 2.2.0

roughike commented Mar 29, 2017

Confirmed on the latest dev branch, looking into it.

yombunker commented Mar 29, 2017

@roughike this is because we trigger a layout phase while on the layout phase, i think what we are missing is that we are not leveraging the measuring phase to calculate the sizes and just lay them out on the payout phase.

roughike commented Mar 29, 2017

Yep. There was no manual requestLayout method calls that were out of place, so I guess the system calls that for us whenever we update the width / height, paddings, etc. while the onMeasure method hasn’t finished.

There’s a lot of optimizations to be done through the library. The weird updateTitleBottomPadding() method for example should be absolutely unnecessary. It was introduced when merging some PR like almost a year ago and to this day, I don’t know why it needs to be here at all.

Читайте также:  Управление homekit с андроида

burhanaksendir commented Mar 30, 2017

I resolved this using android.support.v7.widget.AppCompatTextView:

class BottomBarBadge extends android.support.v7.widget.AppCompatTextView <

yombunker commented Mar 30, 2017

@burhanaksendir if that’s teh fix, then it will be coming in the next days because that’s part of the change i’m working on

nextdimension commented Apr 26, 2017

Its still bugged, any eta on fix?

JDDJJ commented May 3, 2017

when will this bug be fixed? this bug will cause UI stop when app open for long time.

nextdimension commented May 3, 2017

Its been 1 year and no one fixed it, I’d say they don’t know how to, or can’t. I’ll just use a different bottom bar.

yombunker commented May 4, 2017

@nextdimension @JDDJJ well this library wasn’t maintained for a while, And i just started helping about like 2 months ago, but, this is just like a side thing, i’m like 60% done with a huge refactoring in how the BottomBar works, which would make it better while still being backwards compatible. But, i’m super swamped with work this weeks that i haven’t been able to finish it. But, don’t worry @nextdimension i know how to do it, is already solved, the missing thing is not that is other things before the next release is ready. But, you are always free to use other libraries, or if you want you can contribute Pull Request to improve it as well, i try to take a look to PR as they arrive.

JDDJJ commented May 15, 2017


massimobio commented Jun 8, 2017

I tried the fix recommended @burhanaksendir but the warnings and the 1-2sec lag on rotation remains

Albul commented Oct 29, 2017 •

Why do you need this updateTitleBottomPadding ?
What if just add to bb_bottom_bar_item_shifting.xml

.
android:paddingBottom=»10dp»
./>

Источник

Android — View.requestLayout не работает в OnLayoutChangeListener

Мне нужно использовать GridLayout для моего приложения. Проблема GridLayout — ограничение веса, поэтому я должен масштабировать размер своих детей во время выполнения. Я делаю это с помощью OnGlobalLayoutListener .

Дети моего GridLayout — это два Button , которые имеют ширину родителя и половину высоты родителей. Один Button выше и один Button ниже.
Если щелкнуть верхний Button , я хочу изменить размер GridLayout на 500 по ширине и высоте и 700 по ширине и высоте.
После щелчка на верхнем Button значение Button должно масштабироваться правильно, но они этого не делают.

Кто-нибудь может сказать мне, что делать?

Как я могу сказать ContentView обновить себя и своих детей? Я ищу элегантное решение.

Спасибо за ответы!

Я столкнулся с той же проблемой. Я предполагаю, что Android не закончил вычислять новый макет, когда вызывается onLayoutChanges() , и пересчет не может быть вызван из метода.
Решение заключается в использовании Handler, чтобы опубликовать изменения макета в конце потока пользовательского интерфейса.

Я не уверен в requestLayout() , возможно, заменил его другим вызовом setLayoutParams() . Вероятно, он имеет тот же эффект.

Итак, реализуйте свой повторный макет в классе, реализующем Runnable , создайте экземпляр Handler в onCreate() и в onLayoutChanges() создайте экземпляр класса Runnable и разместите его в обработчике:

Большое вам спасибо за ваш ответ. Я думал, что никто не имеет идеи.

Ваше «решение» интересно, но, к сожалению, немного неправильно. Оптически он отлично работает, но на заднем плане у вас есть бесконечный цикл.

Вы увидите это, если вы установите счетчик в тексте одного из Button s. Счетчик бесконечно увеличивается.

Установка нового размера макета Button s ‘в Handler сопровождается новым вызовом OnLayoutChangeListener , и этот Listener снова запускает Handler и так далее.

Вы получите ту же проблему, если используете OnGlobalLayoutListener вместо OnLayoutChangeListener с Handler .

Причина в следующем. view.requestLayout() или view.setLayoutParams(…) не работает в методе onLayoutChange , но работает в методе onGlobalLayout или в Handler , который создает новый поток.

Теперь часть, которую я действительно не понимаю:

Успешный вызов child.requestLayout() вызывает новый вызов родительского метода onLayoutChange . Это характерно, потому что родительский макет не должен меняться снова.

Как бы то ни было, небольшая логика if/else решает бесконечные вызовы.

Читайте также:  Samsung android создать папку

В этом случае я использую OnGlobalLayoutListener вместо комбинации OnLayoutChangeListener / uiHandler .;-) Логика if/else — то же самое.

Мой оригинальный вопрос, почему requestLayout не работает в onLayoutChange , все еще открыт, но удовлетворительное решение было представлено здесь, поэтому я счастлив.

Источник

Android: requestLayout () неправильно вызван

При попытке раздуть макет внутри ListView возникает следующая ошибка:

Я пытаюсь раздуть макет внутри ListView следующим образом:

Развернутая компоновка может выглядеть так же просто, как и следующая, и будет по-прежнему выдавать ошибку

Я рассмотрел аналогичные вопросы, и никакие решения, как представляется, не работают Вопрос 1 , Вопрос 2 , Вопрос 3 .

Кто-нибудь знает, что вызывает этот тип ошибок? Любые советы по устранению неполадок? Для большего контекста этот ListView отображается внутри Fragment в ViewPager

ОБНОВИТЬ

Вот полный XML-макет (минус куча атрибутов), который все еще приводит к проблеме

Исходя из этого, я думаю, что сам XML не является проблемой, если только он не связан с тем, что я использую ViewPager и Fragments

Активация функции быстрого прокрутки ListView в вашем коде через ListView.setFastScrollEnabled(true) вызовет эту ошибку, и вы начнете видеть

RequestLayout () неправильно вызван android.widget.TextView <…>во время компоновки: выполняется второй переход макета

Сообщение в консоли.

Эта ошибка должна была быть введена в одном из обновлений KitKat (4.4.x), поскольку я не видел ее с исходной версией KitKat (4.4.0). Помимо уродливого консольного спама с отладочным сообщением сверху, похоже, никаких других воздействий (возможно, производительности в некоторых случаях, которые я еще не тестировал), похоже, нет.

PS: это не первый случай, когда функция быстрого прокрутки прослушивается, например https://code.google.com/p/android/issues/detail?id=63545 , 63545 исправлено в KitKat 4.4.3, но 75516 всплыло После этого -> кажется, является досадной темой для google 😉

EDIT 12 мая 2015:

Я обновил свой Nexus 7 до Android 5.1 несколько минут назад (раньше был 5.0) и не видел эту проблему в этой новой версии. Поскольку появление индикатора FastScroll также изменилось в 5.1, я предполагаю, что Google исправил эту проблему или, по крайней мере, прокомментировал эти уродливые строки, которые спамали консоль …

75516 и 82461 все еще «неразрешены», но я думаю, что они относятся к одной и той же проблеме, которая теперь решена в 5.1.

Проблема в том, что, хотя метод getView() вашего адаптера отображает ваш макет, а какой-то другой код пытается получить доступ к этому представлению, чтобы отобразить его, что привело к столкновению.

Обратите внимание, что некоторые методы, которые, возможно, вы не позаботитесь (например, setScale() , setTypeFace() ), действительно вызывают requestLayout() , поэтому было бы интересно, что вы делаете после вашего заявления на инфляцию.

Я исправил эту проблему, отключив fastScroll в ListView в XML.

Это может произойти, если вы используете стороннее расширение ListView. Замените это стандартным ListView и проверьте, не вызывает ли это ошибку.

У меня была схожая проблема. Проверьте макет Android: выполните второй макет и мой ответ.

У меня была такая же проблема с Kitkat 4.4.4 на Motorola X с Genymotion. В моем случае элемент списка – это простой CheckedTextView, и ошибка произошла в AppCompatCheckedTextView.

В качестве обычной реализации я раздул элемент из файла макета XML, как показано ниже:

После некоторых попыток выяснилось, что это связано с инфляцией XML. Я не знаю причину, но в качестве решения я решил раздуть элемент списка по коду и установить все свойства с помощью кода.

Это закончилось так:

В моем случае это предупреждение помешало появлению кнопки в устройствах API 21. Ранее была установлена ​​кнопка GONE.

Единственным обходным решением, которое я получил, была установка INVISIBLE вместо GONE для API 21. Это было не настоящее решение, но это было приемлемо для меня.

Я только публикую это, потому что он может быть полезен кому-то.

Попробуйте снять textSize из xml и установить его в Java-коде. Думаю, это заставило его выложить дважды.

В моем случае (Samsung Galaxy S4, API 21) это произошло в ListView с EditTexts. У меня есть слушатель для проверки поля. Что-то вроде:

После настройки фокуса в одном из этих EditTexts вызывается вышеуказанная проверка. После этого TextView изменится (TextView содержит сообщение об ошибке и лежит над EditText). Установка фокуса на второй или третий EditText привела к постоянному запросу первого EditText и возврату к текущему. Приложения выполняются в бесконечном цикле запросов (фокус edittext 1, unocus edittext 1, focus 3, unocus 3, focus 1 и т. Д.).

Я попытался установить listView.setFastScrollEnabled (false). Также я попробовал requestLayout () некоторых элементов, например, https://github.com/sephiroth74/HorizontalVariableListView/issues/93 без каких-либо шансов. В настоящее время я сделал TextView фиксированной ширины и высоты в XML:

После некоторых экспериментов я заметил, что высота 20dp может быть заменена на «wrap_content». Но если текст слишком длинный, что делится на 2 строки, приложение снова попадает в бесконечный цикл. Итак, android:singleLine=»true» поможет. Это устарело, но удивительно android:maxLines=»1″ с android:lines=»1″ не помогают, поскольку они снова запрашивают макет. В конце концов мы имеем:

Это нехорошее решение, но, по крайней мере, оно прерывает бесконечный цикл.

Для меня эта проблема возникала при вызове setLayoutParams() . Решение было размещено на петлере, как указано здесь

Источник

Использование forceLayout (), requestLayout () и invalidate ()

Я немного смущен о ролях методов forceLayout() , requestLayout() и invalidate() класса View .

Когда они будут называться?

Чтобы лучше понять ответы, предоставленные François BOURLIEUX и Dalvik, я предлагаю вам взглянуть на эту удивительную диаграмму жизненного цикла View by Arpit Mathur :

invalidate()

Вызов invalidate() выполняется, если вы хотите запланировать перерисовку представления. Это приведет к onDraw что onDraw будет вызван в конечном итоге (вскоре, но не сразу). Примером того, когда пользовательское представление вызывало бы это, является изменение свойства текста или фона.

Представление будет перерисовано, но размер не изменится.

requestLayout()

Если что-то изменится в вашем представлении, что повлияет на размер, вы должны вызвать requestLayout() . Это вызовет onMeasure и onLayout не только для этого представления, но и для линии для родительских представлений.

При requestLayout() не гарантируется результат onDraw (вопреки тому, что подразумевает диаграмма в принятом ответе), поэтому его обычно объединяют с invalidate() .

Примером этого может служить изменение пользовательского ярлыка. Этикетка изменит размер и, следовательно, необходимо будет переоценить и перерисовать.

forceLayout()

Вызов forceLayout() если вы хотите только передать содержимое своего собственного представления, но не нужно инициировать повторное измерение всего дерева представлений (все родительские представления). Если у вас была пользовательская ViewGroup которая не меняла свой собственный размер, но для переоценки и ретрансляции своих детей это было бы подходящей ситуацией для вызова forceLayout() .

В принципе, вызов requestLayout() приводит к вызову parent.requestLayout() , но вызов forceLayout() не выполняется.

Дальнейшее изучение

  • Создание класса просмотра: добавление свойств и событий (полезные документы)
  • Просмотр документации
  • View исходный код

Для меня вызов invalidate() только обновляет представление, а вызов requestLayout() обновляет представление и вычисляет размер представления на экране.

Вы используете invalidate () в представлении, которое вы хотите перерисовать, оно сделает его onDraw (Canvas c) для вызова, а requestLayout () сделает повторную визуализацию всего кадра (фаза измерения и фаза позиционирования). Вы должны использовать его, если вы изменяете размер дочернего представления во время выполнения, но только в отдельных случаях, таких как ограничения из родительского представления (под этим я подразумеваю, что высота или ширина родителя – WRAP_CONTENT и поэтому соответствуют мерам детей, прежде чем они смогут их снова обернуть)

Этот ответ forceLayout() отношении forceLayout() .

Как вы можете видеть в коде forceLayout() он просто отмечает представление как «нуждается в ретрансляторе», но он не планирует и не запускает этот ретранслятор. Ретрансляция не произойдет до тех пор, пока в какой-то момент в будущем родительский вид представления не будет изложен по какой-либо другой причине.

Существует также гораздо большая проблема при использовании forceLayout() и requestLayout() :

Предположим, вы вызвали forceLayout() на представлении. Теперь при вызове функции requestLayout() на requestLayout() этого представления Android будет рекурсивно вызывать requestLayout() для предков этого потомка. Проблема в том, что она остановит рекурсию в представлении, на которое вы forceLayout() . Таким образом, requestLayout() никогда не достигнет корня представления и, следовательно, никогда не будет планировать прохождение макета. Весь requestLayout() иерархии представлений ожидает макета, и вызов requestLayout() в любом представлении этого поддерева не приведет к созданию макета. Только вызов requestLayout() в любом представлении вне этого поддерева будет нарушать заклинание.

Я бы рассмотрел реализацию forceLayout() (и как он влияет на requestLayout() чтобы быть сломанным, и вы никогда не должны использовать эту функцию в своем коде.

Источник

Оцените статью