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
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
MessagerequestLayout () incorrectement appelé par android.widget.TextView{...} lors de la mise en page: exécution du second layout pass
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.
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.
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"
/>
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
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.
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;
}
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);
}
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.
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.