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); 

     }