2014-09-03 3 views
0

J'ai un GridView dans mon projet en utilisant le StaggeredGridView (https://github.com/etsy/AndroidStaggeredGrid). Chaque élément est composé d'un ImageView et d'un TextView et la hauteur des différents ImageViews change de l'un à l'autre. Le problème vient quand on fait défiler vers le haut, à cause du recyclage de la vue, quand les images se rechargent, à cause des hauteurs différentes, le StaggeredGridView 'rebondit' un peu et c'est assez ennuyeux. J'essaye d'enlever le rebondissement, juste comme l'application de Pinterest ou d'Etsy (ceux-ci ne rebondissent pas du tout et semblent garder le rapport d'aspect en mémoire). J'ai mais je n'ai pas réussi à comprendre comment.Android GridView. Éviter les rebonds/bosses pendant le défilement

Voici un code:

GridItemAdaptem

@Override 
    public View getView(final int position, View convertView, final ViewGroup parent) { 
     final Holder holder; 

     if(convertView!=null){ 
      holder = (Holder) convertView.getTag(); 
     } else { 
      LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
      convertView = inflater.inflate(R.layout._grid_guide_item, parent, false); 
      holder = new Holder(convertView); 
      convertView.setTag(holder); 
     } 

     final Guide guide = this.guides.get(position); 
     holder.pic.post(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        int height = Integer.parseInt(guide.getCover().getHeight()) * holder.pic.getWidth()/Integer.parseInt(guide.getCover().getWidth()); 
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(holder.pic.getWidth(), height); 
        holder.pic.setScaleType(ImageView.ScaleType.FIT_XY); 
        holder.pic.setLayoutParams(params); 
        ImageAware imageAware = new ImageViewAware(holder.pic, true); 
        imageLoader.displayImage(
         FavoAPI.getImageURL(guide.getCoverId()), 
         imageAware 
        ); 
       } catch (NotCoverException ignored) {} 
      } 
     }); 
     holder.name.setText(guide.getName()); 
     holder.user.setText(Finals.AUTHOR + guide.getOwner().getFull_name()); 

     return convertView; 
    } 

    static class Holder { 
     @InjectView(R.id._grid_item_user) 
     TextView user; 
     @InjectView(R.id._grid_item_name) 
     TextView name; 
     @InjectView(R.id._grid_item_pic) 
     RoundedCornerImageView pic; 

     public Holder(View view){ 
      ButterKnife.inject(this, view); 
     } 
    } 

grid_item.xml

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    style="@style/GuidePreviewGuideCardItem" 
> 
    <nl.favoThings.favoroute.Views.Widgets.RoundedCornerImageView 
     android:id="@+id/_grid_item_pic" 
     style="@style/gridItem_image" 
    /> 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" 
     android:padding="@dimen/formDefault_tinnyMargin" 
    > 
     <TextView 
      android:id="@+id/_grid_item_name" 
      style="@style/gridItem_bigText" 
      /> 

     <TextView 
      android:id="@+id/_grid_item_user" 
      style="@style/gridItem_smallText" 
      android:layout_width="wrap_content" 
      /> 
    </LinearLayout> 
</LinearLayout> 

Le style de la ImageView

<style name="gridItem_image"> 
     <item name="android:layout_width">fill_parent</item> 
     <item name="android:layout_height">wrap_content</item> 
     <item name="android:layout_margin">@dimen/gridItem_image_margin</item> 
     <item name="android:padding">@dimen/gridItem_image_margin</item> 
     <item name="android:background">@color/white</item> 
     <item name="android:scaleType">fitStart</item> 
     <item name="android:adjustViewBounds">true</item> 
     <item name="android:src">@drawable/default_route</item> 
    </style> 

Répondre

0

Ditch le Runnable. Il suffit que ce code s'exécute directement dans l'appel getView(). Lorsque votre code est positionné, vous exécutez Runnable sur le fil de l'interface utilisateur. Cela signifie que vous n'avez aucun avantage à l'utiliser dans la méthode getView() ... qui s'exécute également sur le thread de l'interface utilisateur. Vous voyez le redimensionnement parce que le View renvoyé par getView() est rendu à l'écran avant que votre Runnable puisse s'exécuter. Quand il le fait, il met à jour le View et vous voyez le changement visuel. En se débarrassant du Runnable, votre View sera à la taille correcte avant qu'il ne soit rendu à l'écran.

+0

Le fil est utilisé pour pouvoir afficher l'image par défaut avec la hauteur de l'image finale pendant son chargement. J'ai supprimé le fil et le problème est toujours là. En fait, c'était avant même d'implémenter le thread. – Viperey

+0

Hmmm ... êtes-vous certain que la taille finale de l'image correspond à ce que vous avez calculé avant la main? Je produirais ce que les tailles de vue sont avant et après que l'image finale se charge. Je suppose que vous verrez que les tailles diffèrent, ce qui explique le changement visuel de la taille. –

+0

Ummmm, j'ai fait plusieurs tests en implémentant tout ce code, car ça me rendait fou (le tout en général) En tout cas, je vais essayer ça. Merci beaucoup pour votre temps et vos réponses;) – Viperey

Questions connexes