web-dev-qa-db-fra.com

Comment obtenir la hauteur d'un article de recyclerview dans "onBindViewHolder"

La hauteur de l'élément de RecyclerView est non fixée , je dois définir l'image d'arrière-plan pour chaque élément. Je souhaite donc obtenir la hauteur de l'élément de recyclerview pour redimensionner l'image, mais la fonction itemView.getHeight() renvoie toujours 0 dans onBindViewHolder.

J'ai essayé de chercher beaucoup de questions ou d'articles, mais je ne peux toujours pas obtenir une bonne soluation.

14
zys

Court

Mesurer la vue manuellement

view.measure(
             View.MeasureSpec.makeMeasureSpec(recyclerViewWidth, View.MeasureSpec.EXACTLY),
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

et obtenez la hauteur avec view.getMeasuredHeight()

Contexte

Une vue renverra une valeur valide pour View.getHeight()only après avoir été mesurée. La mesure elle-même sera automatiquement effectuée par le système lorsque la vue est sur le point d'être affichée à l'écran.

Lorsque Android souhaite afficher la mise en page, il appelle de manière récursive la fonction view.layout() pour chaque vue de l'arborescence. Chaque parent indique à ses enfants les contraintes qu’ils pourraient avoir (largeur/hauteur) et leur demande d’appeler eux-mêmes view.measure(). En conséquence, la vue stockera les valeurs mesurées BASÉES sur les contraintes des membres désignés (MeasuredHeight/Width). Notez qu'à ce stade, view.getMeasuredHeight() tiendra la valeur tandis que view.getHeight() sera toujours invalide. view.getHeight() renverra une valeur valide uniquement lorsque la vue aura une hauteur réelle dans la hiérarchie de l'interface utilisateur.

Résumer

Ainsi, pour connaître la hauteur d'un élément de vue, avant qu'il ait été mesuré et défini par le système, nous devrons appeler la fonction view.measure() manuellement.

La fonction de mesure attend 2 paramètres dérivés de la vue LayoutParams + les contraintes parent.

Dans l'exemple de code ci-dessus, nous mesurons la vue en forçant sa largeur àEXACTEMENTla largeur du parent (le RecycleView), et la hauteur n'est pas limitée.

31
Eyal Biran

Je vous suggère de définir plusieurs fichiers de présentation avec les hauteurs prévues et de les gonfler en fonction de certains critères de votre ensemble de données.

VH onCreateViewHolder (ViewGroup parent, 
                int viewType){
if(some condition){
//inflate layout 1
}else{
//inflate layout 2
}

ou comme répondu ici : vous pouvez obtenir les mesures lors de l'initialisation du titulaire de la vue

viewHolder.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int width = viewHolder.getMeasuredWidth();
int height = viewHolder.getMeasuredHeight();
9
Mina Samy

en utilisant ce code pour obtenir la hauteur d'élément de la vue recycleur:

view.getViewTreeObserver().addOnGlobalLayoutListener(new 
         ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //don't forget remove this listener
        view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        //get item height here
        int itemHeight = v.getHeight();
    }
});
0
Tinfu

Que dis-tu de ça:

view.post(() -> {
   int width = view.getMeasuredWidth();
   int height = view.getMeasuredHeight();
}