Подтвердить что ты не робот

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

4b9b3361

Ответ 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 !! все будет хорошо работать