24

Tôi có vấn đề này - chỉ cho mục đích thử nghiệm tôi đã thêm ParseFile vào một trong số ParseObject từ danh sách nhận được. Thay vì chỉ hiển thị nó trong hàng đó, nó cho thấy mỗi 4-5 hàng, đôi khi nhiều hơn, đôi khi ít hơn. Tôi cho rằng chế độ xem tái chế có liên quan đến việc này. Kỳ lạ, các dữ liệu khác (bị xóa khỏi ví dụ này) hoạt động tốt với biến số position.Recyclerview Adapter và Glide - cùng một hình ảnh 4-5 hàng

@Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     if(parseList.get(position).get("logo") != null){ 
      ParseFile image = (ParseFile) parseList.get(position).get("logo"); 
      String url = image.getUrl(); 
      Glide.with(context) 
        .load(url) 
        .placeholder(R.drawable.piwo_48) 
        .transform(new CircleTransform(context)) 
        .into(holder.imageView); 


     } 

    } 

Trả lời

49

Câu trả lời ở đây không đúng, mặc dù chúng đang đi đúng hướng.

Bạn cần gọi số Glide#clear(), không chỉ đặt hình ảnh có thể vẽ thành rỗng. Nếu bạn không gọi clear(), tải không đồng bộ hoàn tất không đúng thứ tự vẫn có thể gây ra các sự cố về xem lại. Mã của bạn sẽ trông như thế này:

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    if (parseList.get(position).get("logo") != null) { 
     ParseFile image = (ParseFile) parseList.get(position).get("logo"); 
     String url = image.getUrl(); 
     Glide.with(context) 
       .load(url) 
       .placeholder(R.drawable.piwo_48) 
       .transform(new CircleTransform(context)) 
       .into(holder.imageView); 
    } else { 
     // make sure Glide doesn't load anything into this view until told otherwise 
     Glide.clear(holder.imageView); 
     // remove the placeholder (optional); read comments below 
     holder.imageView.setImageDrawable(null); 
    } 
} 
+0

Bạn có thể giải thích thêm về điều đó không? Câu trả lời trước đây đang hoạt động tốt, nhưng tôi tưởng tượng phương thức 'clear() 'không được thực hiện chỉ từ không khí mỏng. –

+0

Chúng hầu như chỉ hoạt động. Nếu bạn gọi onBindViewHolder và bắt đầu tải cho vị trí có biểu trưng cho một chế độ xem nhất định, sau đó gọi lại onBindViewHolder với cùng ViewHolder trước khi tải xong, bạn sẽ thấy hình ảnh cũ thay vì chế độ xem trống. Điều kiện chủng tộc này ít phổ biến hơn lỗi trước của bạn, nhưng vẫn có thể. –

+0

Ngoài ra tôi nên làm rõ tôi đã viết thư viện và phương thức clear(). Trường hợp sử dụng này ở đây là một ví dụ tuyệt vời về lý do tại sao phương thức clear() tồn tại :). Bạn phải luôn bắt đầu tải mới (hủy tải cũ cho bạn) hoặc tự hủy tải khi bạn đang sử dụng lại chế độ xem. –

1

Khi "logo" rỗng, bạn sẽ có được hình ảnh được tái chế thay vì xóa ảnh đó. Thêm mã này để xóa hình ảnh đúng cách:

holder.imageView.setImageDrawable(null); 
1

Trong RecyclerView mỗi hàng được tái chế với dữ liệu mới. Trong mã của bạn, bạn đang đặt ImageView chỉ khi không phải là null và không làm gì cả. Trong trường hợp này khi nó không rỗng ImageView sẽ hiển thị hình ảnh cũ vì bạn không override cho đối tượng hiện tại. Bạn có thể sửa lỗi này bằng cách thêm điều kiện khác và đặt ImageView để trống/trống bất kỳ thứ gì.

@Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     if(parseList.get(position).get("logo") != null){ 
      ParseFile image = (ParseFile) parseList.get(position).get("logo"); 
      String url = image.getUrl(); 
      Glide.with(context) 
        .load(url) 
        .placeholder(R.drawable.piwo_48) 
        .transform(new CircleTransform(context)) 
        .into(holder.imageView); 


     } 
     else{ 
      holder.imageView.setImageDrawable(null); 
     } 
    } 
+1

Tôi biết nó rằng đó là một cái gì đó với quan điểm tái chế, nhưng chưa bao giờ nghĩ theo cách đó. Cảm ơn rất nhiều vì điều này, nó hoạt động ngay lập tức :) –

+0

Câu trả lời này chưa hoàn thành. Bạn cũng cần gọi Glide.clear() trên chế độ xem hình ảnh được đề cập, nếu không bạn vẫn có thể thấy các sự cố tái sử dụng ô iwhen tải không đồng bộ hoàn thành sau này. –

+0

@samajudd Tôi chỉ tìm thấy một - vì vậy tôi nên gọi cả hai 'setImageDrawable (null)' và 'Glide.clear()'? –

2

Có lẽ bạn cần phải thử một cái gì đó giống như

.signature(new StringSignature(String.valueOf(System.currentTimeMillis()))) 

mẫu này:

Glide.with(context) 
       .load(url) 
       .placeholder(R.drawable.progress_animation) 
       .crossFade() 
       .signature(new StringSignature(String.valueOf(System.currentTimeMillis()))) 
       .error(R.drawable.image_error_404) 
       .into(iv); 
Các vấn đề liên quan