Android: requestLayout () incorrectement appelé

l'erreur suivante se produit lorsque je tente de gonfler un layout dans un ListView :

requestLayout() improperly called by android.widget.TextView{...} during layout: running second layout pass

j'essaie de gonfler une disposition à l'intérieur d'un ListView comme suit:

@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{...}
}

la mise en page étant gonflée peut sembler aussi simple que ce qui suit, et produira toujours l'erreur

<TextView
    android:id="@+id/txt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="@dimen/txt_size"/>

j'ai examiné des questions similaires, et aucune solution trouvée semblent fonctionner Question 1 , Question 2 , Question 3 .

est-ce que quelqu'un sait ce qui cause ce type d'erreur? Tous les conseils de dépannage? Pour plus de contexte, ce ListView est affiché dans un Fragment dans un ViewPager

UPDATE

Voici la mise en page XML complète (moins un tas d'attributs), qui entraîne toujours le problème

<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>

Basé sur ceci, je pense que le XML lui-même n'est pas un problème, sauf s'il a à voir avec le fait que j'utilise un ViewPager et des Fragments

39
demandé sur Community 2014-07-06 22:28:27

9 réponses

ce problème semble être un bug dans l'implémentation android, s'il vous plaît voir: https://code.google.com/p/android/issues/detail?id=75516

activer la fonction de défilement rapide d'un ListView dans votre code via ListView.setFastScrollEnabled(true) va déclencher ce bug et vous allez commencer à voir le

requestLayout () incorrectement appelé par android.widget.TextView{...} lors de la mise en page: exécution du second layout pass

Message

dans votre console.

ce bogue doit avoir été introduit dans L'un des KitKat (4.4.x) les mises à jour, comme je ne l'ai pas vu avec la première KitKat (4.4.0) communiqué de presse. A part le spamming de la console moche avec le message de débogage venant d'en haut, il ne semble pas y avoir d'autres impacts (peut-être des performances dans certains cas, que je n'ai pas testées).

Cheers

PS: ce n'est pas la première fois que la fonction fast scroll est buggé, par exemple, https://code.google.com/p/android/issues/detail?id=63545 , 63545 a été corrigé dans KitKat 4.4.3, mais 75516 poped vers le haut par la suite --> semble être un sujet contrarié pour google ;-)

MODIFIER le 12 Mai 2015:

j'ai mis à jour mon Nexus 7 pour Android 5.1 il y a quelques minutes (était en cours d'exécution 5.0 avant) et a cessé de voir ce problème dans cette nouvelle version. Comme l'apparence de L'indicateur de FastScroll a également changé en 5.1, je suppose que google a corrigé ce problème ou au moins commenté ces lignes laides qui ont spammé la console...

75516 & 82461 sont toujours "non résolus", mais je suppose que ceux-ci se réfèrent à la même question, qui est maintenant résolu dans 5.1.

41
répondu darksaga 2015-05-12 19:26:46

le problème est que pendant que la méthode getView() de votre adaptateur affiche votre disposition un autre code essaie d'accéder à cette vue pour l'afficher, résultant en une collision.

notez que certaines méthodes, que peut-être vous ne prenez pas soin de (comme setScale() , setTypeFace() ) appeler en effet requestLayout() , il serait donc intéressant ce que vous faites après votre déclaration inflate.

15
répondu axl coder 2017-10-02 12:09:47

j'ai corrigé ce problème en désactivant fastScroll sur le ListView en XML.

<ListView
    android:id="@+id/mListview"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"

    android:fastScrollEnabled="false"
/>
4
répondu Joaquin Iurchuk 2015-03-11 16:42:04

pour moi, ce problème se produisait lors d'un appel setLayoutParams() . La solution était de poster un runnable sur le looper comme indiqué ici

3
répondu VladimirVip 2017-05-17 23:35:22

cela peut se produire si vous utilisez une extension tierce de ListView. Remplacez-le par ListView standard et vérifiez si L'erreur persiste.

j'ai eu le même problème. S'il vous plaît vérifier mise en page Android: exécution de la deuxième mise en page passe et ma réponse.

1
répondu ksarmalkar 2017-05-23 11:54:43

J'ai eu le même problème avec Kitkat 4.4.4 sur Motorola X avec Genymotion. Dans mon cas, l'élément list est un simple CheckedTextView et l'erreur s'est produite dans AppCompatCheckedTextView.

comme une mise en œuvre normale, j'ai gonflé l'élément du fichier de mise en page XML comme ci-dessous:

if (convertView == null) {
  convertView = inflater.inflate(R.layout.checkable_list_entry, parent, false);
}

après quelques essais j'ai découvert que cela a quelque chose à voir avec l'inflation XML. Je ne connais pas la cause profonde, mais comme solution j'ai décidé de gonfler la liste point par code et définir toutes les propriétés par code aussi.

il a fini comme ceci:

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;
}
1
répondu Thomas R. 2015-11-19 10:12:19

dans mon cas cet avertissement a empêché un bouton d'apparaître dans les appareils API 21. Le bouton visibility était précédemment réglé sur GONE.

la seule solution que j'ai trouvée était de configurer à INVISIBLE au lieu de GONE for API 21. Ce n'était pas une vraie solution, mais c'était acceptable pour moi.

je poste seulement ceci parce qu'il peut être utile de quelqu'un.

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
    theButton.setVisibility(View.INVISIBLE);
}
else {
    theButton.setVisibility(View.GONE);
}
1
répondu Javier Torón 2016-08-15 23:58:40

dans mon cas (Samsung Galaxy S4, API 21) c'est arrivé dans ListView avec EditTexts. J'ai un auditeur pour la validation des champs. Quelque chose comme:

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);
        }
    }
});

après avoir défini focus dans l'un de ces textes, une vérification ci-dessus est appelée. Après cela, un TextView va changer (le TextView contient un message d'erreur et se trouve sur le texte édité). La mise au point du deuxième ou du troisième texte édité a conduit à la requête permanente du premier texte édité et au retour à current. Un les applications s'exécute dans une boucle infinie de demandes (focus edittext 1, unfocus edittext 1, 3, unfocus 3, axe 1, etc).

j'ai essayé de mettre listView.setFastScrollEnabled (false). J'ai aussi essayé un requestLayout () de certains éléments comme dans https://github.com/sephiroth74/HorizontalVariableListView/issues/93 sans aucune chance. Actuellement, j'ai fait que TextView de la largeur fixe et la hauteur en XML:

<TextView
    android:id="@+id/error"
    android:layout_width="match_parent" (or "200dp", but not "wrap_content")
    android:layout_height="20dp"
    .../>

après quelques expériences j'ai remarqué qu'une hauteur de 20dp peut être remplacée par "wrap_content". Mais si un texte est trop long, qui se divise en 2 lignes, l'application des captures dans la boucle infinie. Donc, android:singleLine="true" aidera. Il est déprécié, mais étonnamment android:maxLines="1" avec android:lines="1" n'aident pas car ils demandent à nouveau layout. Finalement nous avons:

<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"/>

ce n'est pas une bonne solution, mais au moins ça casse la boucle infinie.

1
répondu CoolMind 2016-08-31 18:18:06

essayez d'enlever le textSize du xml et de le configurer en code Java. Je pense que c'est à l'origine pour être disposés deux fois.

0
répondu Gabe Sechan 2014-07-12 06:19:57