web-dev-qa-db-fra.com

Défilement lent de RecyclerView

Je charge des images 400 x 200 dans RecyclerView, mais le défilement est lent sur les appareils 2k. J'utilise Picasso pour charger des images à partir d'une ressource.

Comme vous pouvez le voir dans la démo, les images sont floues sur l'écran 2k, mais si je charge des images à plus haute résolution, la situation empire. Comment résoudre ce problème, je ne charge même pas une grande image, son 400x200?

Démo

Voici mon code card_view.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/card_view"
    card_view:cardPreventCornerOverlap="false"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:layout_margin="8dp"
    card_view:cardCornerRadius="2dp">

    <LinearLayout
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:id="@+id/rel">

        <ImageView
            Android:id="@+id/cardimage"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:scaleType="fitXY"
            Android:src="@drawable/p7"/>

        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="title"
            Android:paddingLeft="16dp"
            Android:paddingRight="16dp"
            Android:paddingTop="16dp"
            Android:paddingBottom="24dp"
            Android:textStyle="bold"
            Android:textSize="24sp"
            Android:id="@+id/cardtitle"
            Android:layout_gravity="center_vertical"/>

    </LinearLayout>

</Android.support.v7.widget.CardView>

Myadapter Code

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {

private Context mContext;
List<Flower> list = new ArrayList<>();

public CardAdapter(Context mContext, List<Flower> list) {
    this.mContext = mContext;
    this.list = list;

}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)   {

    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_view, parent, false);
    return new ViewHolder(itemView);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position)  {

    holder.Flower=getItem(position);
    holder.cardtitle.setText(list.get(position).name);

    Picasso.with(mContext)
            .load(list.get(position).id)
            .placeholder(R.drawable.ic_launcher)
            .into(holder.cardimage);
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

@Override
public int getItemCount() {
    return list.size();
}

public Flower getItem(int i) {
    return list.get(i);
}

public class ViewHolder extends RecyclerView.ViewHolder {

    ImageView cardimage;
    TextView cardtitle;
    Flower Flower;

    public ViewHolder(View itemView) {
        super(itemView);

        cardimage = (ImageView) itemView.findViewById(R.id.cardimage);
        cardtitle = (TextView) itemView.findViewById(R.id.cardtitle);
    }
}
}

MISE À JOUR: je charge des images à partir d'une ressource, je ne télécharge rien

Voici mon tableau

 private void initializeData() {
    flowers = new ArrayList<>();
    flowers.add(new Flower("Flower 1", R.drawable.p8));
    flowers.add(new Flower("Flower 2", R.drawable.p10));
    flowers.add(new Flower("Flower 3", R.drawable.p11));
    flowers.add(new Flower("Flower 4", R.drawable.p8));
    flowers.add(new Flower("Flower 5", R.drawable.photo2));
    flowers.add(new Flower("Flower 6", R.drawable.photo6));
    flowers.add(new Flower("Flower 7", R.drawable.p12));
    flowers.add(new Flower("Flower 8", R.drawable.p9));
    flowers.add(new Flower("Flower 9", R.drawable.p8));
    flowers.add(new Flower("Flower 10", R.drawable.p8));
    flowers.add(new Flower("Flower 11", R.drawable.p8));
    flowers.add(new Flower("Flower 12", R.drawable.p10));
}

MISE À JOUR 2: Les gars, j'ai corrigé la plupart du décalage en définissant adapter.setHasStableIds (true), mais l'application est toujours en retard sur le premier défilement alors que les images ne sont pas encore chargées, comment résoudre ce problème?

MISE À JOUR 3: J'ai juste essayé de charger des images à partir du Web et tout semble fluide, il y a probablement un problème avec le chargement d'images à partir des ressources.

Ok, merci les gars, je vais charger mes images depuis le web.

18
phlosopher_mk

si vous utilisez deux ou plusieurs vues de recycleur comme (RecyclerView et NestedView) essayez ceci

recyclerView.setNestedScrollingEnabled(false);

Source: Recyclerview dans le défilement Nested Scrollview mais ne fait pas défiler rapidement comme Recyclerview normal ou Nested Scrollview

20
Dasser Basyouni

RecyclerView.setHasFixedSize () est-il défini sur true? Je ne suis pas en mesure de reproduire ce décalage ... pouvez-vous s'il vous plaît publier l'intégralité du projet sur git? Vérifiez cela, peut-être que cela peut vous aider: http://antonioleiva.com/recyclerview/

10
Andrei Verdes

Je crois que parfois vous pouvez vous énerver en essayant seulement images statiques en dessinables à afficher votre vue recycleur. Et cela arrive extrêmement en retard.

Pourquoi? Vous peut ne pas obtenir ce problème lors de l'utilisation d'une bibliothèque pour charger une image à partir de l'URL (Picasso, Glide, ...), mais que se passe-t-il avec le même image, même taille et c'est juste dans votre dessinable (pas besoin de télécharger du tout). Et après un certain temps, je me rends compte, Android a fait un truc pour redimensionner une image en dessin pour nous pour obtenir une image correcte dans différents appareils de résolution =. Donc, mon suggestion est de tilisez drawable-nodpi pour stocker votre image afin que Android pour ne pas interférer avec nos images.

7
Nguyen Tan Dat

si vous utilisez Recyclerview en mode vertical et que votre activité contient un autre élément que vous avez ScrollView, vous devez utiliser NestedScrollView au lieu de ScrollView.

comme décrit dans la documentation de Google, NestedScrollView est comme ScrollView, mais il prend en charge le rôle de parent et d'enfant de défilement imbriqué sur les nouvelles et anciennes versions d'Android. Le défilement imbriqué est activé par défaut.

2
MSH

Vous devez obtenir les images de manière asynchrone. Comme c'est le cas maintenant, il bloque pour télécharger réellement l'image.

Laissez la vue d'image vide lorsqu'elle est créée, mais ayez une sorte d'écouteur pour définir l'image lorsqu'elle est téléchargée.

2
BooleanCheese

Cela peut être dû au fait que Picasso a pris du temps pour charger l'image. Utilisez l'instantané ci-dessous et ajustez en conséquence.

Picasso.with (context)
                    .load (url).fit().centerCrop()
                    .error (R.drawable.UserImage)         
                    .into (imageView);

Utilisez fit() et centerCrop() pour éviter la légèreté.

1
Harpreet Singh

J'ai eu un problème de recyclerView laggy lorsque l'un des textView dans le recyclerView recevait des valeurs nulles. Je corrige cela et mon recyclerView a cessé de prendre du retard.

1
S bruce