57 votes

Pourquoi les éléments de ListView ne se développent-ils pas pour envelopper leur contenu ?

J'ai un ListView assez complexe, avec des hauteurs d'éléments de liste variables. Dans certaines conditions, j'ai besoin d'afficher une vue supplémentaire dans un élément de liste, qui est caché par défaut ( View.GONE ). En l'activant ( View.VISIBLE ), l'élément de la liste grandit en hauteur (ou du moins il est censé le faire).

Le problème : Bien que je déclare la disposition Root de l'élément comme étant wrap_content et chaque composant de l'article à fill_parent En effet, la vue que je cache/affiche et qui est censée modifier la hauteur de l'élément est simplement coupée en bas au lieu que son parent (la mise en page de l'élément) augmente en hauteur pour l'afficher entièrement.

Y a-t-il des problèmes liés aux ListViews, à la disposition des éléments et à la hauteur des éléments que j'ai pu manquer ?

Quelques observations supplémentaires :

À des fins de test, j'ai maintenant réduit la disposition des éléments de la liste pour qu'elle ne contienne que le Root LinearLayout et un ImageView. Lorsque je règle la hauteur de la LinearLayout à, par exemple, 1,5 cm. 200dip et l'ImageView à fill_parent je me serais attendu à ce que l'ImageView s'agrandisse jusqu'à ce qu'elle atteigne la limite de l'écran. 200dip limite fixée par son parent.

Cependant, l'image ne sera jamais plus haute que sa ressource bitmap (comme si je l'avais réglé sur wrap_content ) et l'ensemble de l'élément de la liste aura la même hauteur (c'est-à-dire comme si je l'avais également réglé sur wrap_content).

Toutefois, si je règle la hauteur de l'image sur, par exemple, la valeur suivante 200dip l'élément de la liste augmentera en hauteur, de même que la mise en page de l'élément.

En d'autres termes, le layout_height de la mise en page de l'élément de la liste est complètement ignorée, de même que toute valeur de hauteur sur ImageView autre qu'une valeur de pixel codée en dur.

2 votes

HI.. Matthias S'il vous plaît fournissez moi un exemple de travail. Je suis également confronté au même problème, mais je ne suis pas clair sur la façon dont vous avez résolu le problème.

57voto

Matthias Points 17181

J'ai réussi à réparer ça, mais je ne comprends pas pourquoi .

Comme je l'ai mentionné, j'avais défini le layout_height de la mise en page de l'élément de liste à wrap_content (depuis fill_parent n'a pas de sens ici, étant donné qu'une ListView est indéfiniment haute).

Cependant, j'avais défini le layout_height de toutes les vues à l'intérieur de cette disposition à fill_parent . Le problème a disparu lorsqu'on les a réglés sur wrap_content à la place.

Cela soulève deux autres questions :

1) Quelle est la sémantique d'une vue demandant de fill_parent lorsque le parent wraps_content ? Quelle demande de taille est prioritaire ?

2) Comment puis-je faire en sorte qu'une vue remplisse un élément de liste si fill_parent ne fonctionne apparemment pas ?

Merci pour votre contribution.

0 votes

Merci pour cela Matthias =) J'ai eu le même problème avec l'exakt. J'avais également réglé le layout_height sur "fill_parent". Je pensais que c'était évident. Mais vous avez raison, en mettant "wrap_content", cela a résolu le problème. Bizarre...

1 votes

Merci ! Ça me tuait.

0 votes

Ok, pour une raison quelconque, j'avais un problème similaire, mais lorsque je n'avais qu'un seul élément dans la liste, la vue de la liste entière était trop petite dès le premier affichage. Ainsi, lorsque j'augmentais la taille de l'élément, la vue ne s'agrandissait pas. J'ai dû régler la vue sur "fill_parent" pour que cela fonctionne. Maintenant, j'ai besoin de voir ce qui se passe lorsque j'ai beaucoup d'éléments dans la liste.

34voto

PeBek Points 91

Essayez ça : http://www.java2s.com/Code/Android/UI/setListViewHeightBasedOnChildren.htm

public class Utils {

    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter(); 
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
    }     
}

1 votes

Bienvenue à Stack Overflow ! Bien que cela puisse théoriquement répondre à la question, il serait préférable d'inclure les parties essentielles de la réponse ici, et de fournir le lien pour référence.

1 votes

Où exécutez-vous cette méthode pour qu'elle se situe après que l'enfant ait été remesuré ?

2 votes

Joli Mais vous en avez besoin pour faire le params.height tage a px et non une valeur dp valeur.. int dpValue = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); //dp value float density = context.getResources().getDisplayMetrics().density; params.height = (int) Math.ceil(dpValue * density);//pixels value

21voto

CommonsWare Points 402670

Comment gonflez-vous vos rangs ?

Si vous ne l'utilisez pas en ce moment, essayez d'utiliser LayoutInflater#inflate(layoutId, parent, false) (où parent est le AdapterView fourni à getView() ou newView() ) :

v = getLayoutInflater().inflate(R.layout.list_item, parent, false);

0 votes

Bonjour Mark, quelle est la sémantique de la fourniture d'une vue Root à inflate(), mais en mettant attachToRoot à false ? Si la vue gonflée n'est pas attachée à la vue racine, que fait-on d'autre avec cette vue ?

0 votes

Je suis désolé, j'ai oublié de le mentionner : Je passe null pour rootView et false pour attachToRoot. Après tout, la vue est renvoyée par adapter.getView(), qui, je m'y attendais, se charge de l'ajouter à l'arbre des vues.

1 votes

Selon la documentation, "Si elle est fausse, Root est uniquement utilisée pour créer la sous-classe correcte de LayoutParams pour la vue Root dans le XML". Sinon, Android ne sait pas comment attacher l'enfant au parent, et donc je pense qu'il utilise un LayoutParams très générique.

13voto

kirhgoff Points 91

Les problèmes de mise en page peuvent être causés par le fait que ScrollView est l'enveloppe.

Je suis tombé sur une note dans http://developer.Android.com/reference/Android/widget/ExpandableListView.html

"...Remarque : vous ne pouvez pas utiliser la valeur wrap_content pour l'attribut Android:layout_height d'un ExpandableListView en XML si la taille du parent n'est pas non plus strictement spécifiée (par exemple, si le parent était ScrollView, vous ne pourriez pas spécifier wrap_content puisqu'il peut également avoir n'importe quelle longueur. Toutefois, vous pouvez utiliser wrap_content si le parent ExpandableListView a une taille spécifique, telle que 100 pixels."

J'ai supprimé le wrapping ScrollView et la disposition linéaire a commencé à fonctionner correctement. Maintenant, il ne reste plus qu'à comprendre comment envelopper le ScrollView. Que Dieu m'aide

Mais de toute façon, c'est un comportement vraiment bizarre. Je pense que la formulation fill_parent n'est pas vraiment correcte. Lorsque j'utilise l'outil heirarchyviewer, je vois toujours les valeurs WRAP_CONTENT et MATCH_PARENT pour layout_width et leayout_height. Il est donc probable que fill_parent signifie en fait match_parent, ce qui me met en dissonance cognitive.

1voto

roys Points 11

J'utilise "AbsListView.LayoutParams" pour configurer la largeur et la hauteur manuellement dans "Adapter.getView()".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X