Android: requestLayout() неправильно вызван
Следующая ошибка возникает, когда я пытаюсь раздуть макет в ListView
:
requestLayout() improperly called by android.widget.TextView{...} during layout: running second layout pass
Я пытаюсь раздуть макет внутри ListView
следующим образом:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) musicActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
...
}else{...}
}
Развернутая компоновка может выглядеть так же просто, как следующая, и будет по-прежнему выдавать ошибку
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/txt_size"/>
Я рассмотрел похожие вопросы, и никакие найденные решения не работают Вопрос 1, Вопрос 2, Вопрос 3.
Кто-нибудь знает, что вызывает этот тип ошибок? Любые советы по устранению неполадок? Для большего контекста этот ListView
отображается в пределах Fragment
в пределах ViewPager
UPDATE
Вот полный XML-макет (минус куча атрибутов), который все еще приводит к проблеме
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
Исходя из этого, я думаю, что сам XML не является проблемой, если только это не связано с тем, что я использую ViewPager и Fragments
Ответы
Ответ 1
Эта проблема, похоже, является ошибкой в реализации android, см. ниже: https://code.google.com/p/android/issues/detail?id=75516
Активация функции быстрого прокрутки 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;-)
РЕДАКТИРОВАТЬ 12 мая 2015 года:
Я обновил свой Nexus 7 до Android 5.1 несколько минут назад (раньше был запущен 5.0) и не видел эту проблему в этой новой версии. Поскольку внешний вид индикатора FastScroll также изменился в 5.1, я предполагаю, что Google исправил эту проблему или хотя бы прокомментировал эти уродливые строки, которые спамеровали консоль...
75516 и 82461 все еще 'unresolved', но я предполагаю, что они относятся к той же проблеме, которая теперь решена в 5.1.
Ответ 2
Проблема заключается в том, что, пока метод getView()
вашего адаптера отображает ваш макет, какой-то другой код пытается получить доступ к этому представлению, чтобы отобразить его, что привело к столкновению.
Обратите внимание, что некоторые методы, которые, возможно, вы не позаботитесь (например, setScale()
, setTypeFace()
), действительно вызываете requestLayout()
, поэтому было бы интересно, что вы делаете после своего заявления о выпуске.
Ответ 3
Я исправил эту проблему, отключив fastScroll в ListView в XML.
<ListView
android:id="@+id/mListview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fastScrollEnabled="false"
/>
Ответ 4
Для меня эта проблема возникла при вызове setLayoutParams()
. Решение было опубликовать runnable на петлере, как указано здесь
Ответ 5
Это может произойти, если вы используете стороннее расширение ListView. Замените это стандартным ListView и убедитесь, что он по-прежнему вызывает ошибку.
У меня была аналогичная проблема. Пожалуйста, проверьте план Android: выполните второй макет и мой ответ.
Ответ 6
У меня была такая же проблема с Kitkat 4.4.4 на Motorola X с Genymotion. В моем случае элемент списка представляет собой простой CheckedTextView, а ошибка произошла в AppCompatCheckedTextView.
В качестве обычной реализации я раздул элемент из файла макета XML, как показано ниже:
if (convertView == null) {
convertView = inflater.inflate(R.layout.checkable_list_entry, parent, false);
}
После некоторых попыток выяснилось, что это связано с инфляцией XML. Я не знаю причину, но в качестве решения я решил раздуть элемент списка по коду и установить все свойства с помощью кода.
Это закончилось следующим образом:
CheckedTextView view;
if (convertView == null) {
view = new CheckedTextView(parent.getContext());
view.setMinHeight(getResources().getDimensionPixelSize(R.dimen.default_touch_height));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
view.setTextAppearance(R.style.SectionEntry);
} else {
view.setTextAppearance(parent.getContext(), R.style.SectionEntry);
}
view.setBackgroundResource(R.drawable.form_element);
view.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
view.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
} else {
view = (CheckedTextView) convertView;
}
Ответ 7
В моем случае это предупреждение предотвратило появление кнопки в устройствах API 21. Ранее была отображена видимость кнопки GONE.
Единственным обходным решением, которое я получил, была установка INVISIBLE вместо GONE для API 21. Это было не настоящее решение, но это было приемлемо для меня.
Я публикую это только потому, что он может быть полезен кому-то.
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
theButton.setVisibility(View.INVISIBLE);
}
else {
theButton.setVisibility(View.GONE);
}
Ответ 8
В моем случае (Samsung Galaxy S4, API 21) это произошло в ListView с EditTexts. У меня есть слушатель для проверки поля. Что-то вроде:
edit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
error.setVisibility(View.INVISIBLE);
error.setText("");
} else {
String s = edit.getText().toString();
if (s.isEmpty()) {
error.setText("Error 1");
} else if (s.length() < 2 || s.length() > 100) {
error.setText("Error 2");
}
error.setVisibility(View.VISIBLE);
}
}
});
После настройки фокуса в одном из этих 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:
<TextView
android:id="@+id/error"
android:layout_width="match_parent" (or "200dp", but not "wrap_content")
android:layout_height="20dp"
.../>
После некоторых экспериментов я заметил, что высота 20dp может быть заменена на "wrap_content". Но если текст слишком длинный, что делится на 2 строки, приложение снова попадает в бесконечный цикл. Таким образом, android:singleLine="true"
поможет. Он устарел, но удивительно android:maxLines="1"
с android:lines="1"
не помогает, поскольку они снова запрашивают макет.
В конце концов мы имеем:
<TextView
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="#f00"
android:textSize="20sp"
tools:text="Error message"/>
Это не хорошее решение, но, по крайней мере, оно прерывает бесконечный цикл.
Ответ 9
Попробуйте снять textSize из xml и установить его в Java-коде. Я думаю, что это заставило его выложить дважды.
Ответ 10
Иногда вы, возможно, уже исправили проблему, но она по-прежнему сохраняет ту же ошибку, поэтому вам нужно закрыть визуальную студию, а затем удалить все папки bin и obj из ваших проектов, а затем удалить приложение из эмулятора. то walah !! все будет хорошо работать