0

我有一個recyclerview的問題:當我在列表中上下移動時,一些行的圖像被交換(或者通常用其他行的圖像設置幾行)。我認爲問題出在adpter上,但我不明白什麼是錯的。RecyclerView與位圖

myAdapter.java

public class myAdapter extends RecyclerView.Adapter<myAdapter.MyViewHolder> { 

    private List<myItem> myList; 
    private Context context; 

    public class MyViewHolder extends RecyclerView.ViewHolder { 
     public ImageView photo; 
     public TextView name; 

     public MyViewHolder(View view) { 
      super(view); 
      photo = (ImageView) view.findViewById(R.id.rowPhoto); 
      name = (TextView) view.findViewById(R.id.rowName); 
     } 
    } 


    public myAdapter(List<myItem> myList,Context context) { 
     this.myList = myList; 
     this.context = context; 
    } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View itemView = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.row_custom, parent, false); 

     return new MyViewHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(MyViewHolder holder, int position) { 
     myItem c = myList.get(position); 

     if(c.getPathFoto()!=null){ 
      File f = new File(c.getPathPhoto()); 
      Bitmap b = decodeFile(f); 
      holder.photo.setImageBitmap(b); 
     } 

     holder.name.setText(c.getName()); 
    } 



    public Bitmap decodeFile(File f) { 
     try { 
      // Decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 
      BitmapFactory.decodeStream(new FileInputStream(f), null, o); 

      // The new size we want to scale to 
      final int REQUIRED_SIZE=70; 

      // Find the correct scale value. It should be the power of 2. 
      int scale = 1; 
      while(o.outWidth/scale/2 >= REQUIRED_SIZE && 
        o.outHeight/scale/2 >= REQUIRED_SIZE) { 
       scale *= 2; 
     } 

     // Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
     } catch (FileNotFoundException e) {} 
     return null; 
    } 

} 

所有的圖像(我使用)此前已保存在/數據/數據/ MYAPP/app_data文件/ IMAGEDIR(例如/數據/數據/ MYAPP /app_data/imageDir/21432342.png)。

我該如何解決問題?

+0

我建議使用滑翔作爲庫加載圖像,是簡單了很多,而速度更快。 https://github.com/bumptech/glide –

回答

1

我認爲你不清除圖像時,它是空的。

試着改變你的OnBind方法是:

@Override 
public void onBindViewHolder(MyViewHolder holder, int position) { 
    myItem c = myList.get(position); 

    if(c.getPathFoto()!=null){ 
     File f = new File(c.getPathPhoto()); 
     Bitmap b = decodeFile(f); 
     holder.photo.setImageBitmap(b); 
    } else { 
     holder.photo.setImageBitmap(null); 
    } 

    holder.name.setText(c.getName()); 
} 
+0

非常感謝你,它的工作原理 – stackpic91

+0

如果列表中有很多項目,你會被建議現在卸載圖像加載到一個單獨的線程,因爲你的性能會受到影響。嘗試畢加索。 http://square.github.io/picasso/ – Kuffs

0

你肯定有一個併發的問題。 RecyclerView將重新使用該視圖並在其上調用onBindViewHolder。您的方法onBindViewHolder需要時間來加載和設置位圖。

輕鬆(和髒)溶液:
在方法添加​​。這個解決方案對於用戶界面不太好。

@Override 
public synchronized void onBindViewHolder(MyViewHolder holder, int position) { 
    myItem c = myList.get(position); 

    if(c.getPathFoto()!=null){ 
     File f = new File(c.getPathPhoto()); 
     Bitmap b = decodeFile(f); 
     holder.photo.setImageBitmap(b); 
    } 

    holder.name.setText(c.getName()); 
} 

很好的解決:
您必須使用其他線程的位圖解碼。並在致電.setImageBitmap(Bitmap)之前,檢查它是否總是良好的位圖。例如,您可以通過設置持有人的位置來實現此目的。

+0

該Kuff答案解決我的具體(愚蠢)的問題,但謝謝你的建議,使用另一個線程來解碼位圖 – stackpic91

1

那麼你可以嘗試第三方庫像畢加索或下滑,使事情變得更簡單 Picasso Glide

@Override 
    public void onBindViewHolder(MyViewHolder holder, int position) { 
     myItem c = myList.get(position);   
     Picasso.with(context) 
       .resize(desiredWidth,desiredHeight) 
       .load(new File(c.getPathPhoto())).into(holder.photo); 

     }