为什么不起作用notifyItemChanged

时间:2016-12-15 04:43:34

标签: android android-recyclerview notifydatasetchanged

我知道这可能是一个愚蠢的问题,但我找不到答案。 我求你帮忙。

我有一个使用LinearLayoutManager的RecyclerView和一个自定义的RecyclerView.Adapter。

我的数据类:

public class Img extends ArrayList<Img> {
    int id = 0;
    String filepath = "";
    boolean checked = false;
    int progress = 0;

    ... getters and setters...
}

活动代码:

    File folder = new File("My path");
    File[] files = folder.listFiles();
    int id = 0;
    for (File file : files) {
        if (!file.isDirectory()) {
            Img img = new Img();
            img.setId(id);
            img.setFilepath(file.toString());
            imgs.add(img);
            ++id;
        }
    }

    mAdapter = new GalleryAdapter(getApplicationContext(), imgs);
    RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getApplicationContext(), 2);
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(mAdapter);

和适配器:

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        Img item = imgs.get(position);
        holder.txt.setText(String.valueOf(item.getProgress()));
        holder.thumbnail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               File source = new File(imgs.get(position).getFilepath());
               String strFileName = source.getName();
               File destination = new File("My path" + "/" + strFileName);

               try {
                   InputStream input = null;
                   OutputStream output = null;
                   long lenghtOfFile = source.length();
                   int count;
                   try {
                       input = new FileInputStream(source);
                       output = new FileOutputStream(destination);
                       byte[] data = new byte[1024];
                       long total  = 0;
                       int xc2 = 0;
                       while ((count = input.read(data)) != -1) {
                          total += count;
                          int xc = (int) ((total * 100) / lenghtOfFile);

                          output.write(data, 0, count);
                          imgs.get(position).setProgress(xc);
                          notifyItemChanged(position);
                          try {
                              Thread.sleep(20);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  } finally {
                   output.flush();
                   output.close();
                   input.close();
                  }
            } catch (IOException e) {
               e.printStackTrace();
            }
        }
  });

为什么notifyItemChanged(position)只在操作完成后才被触发并提交给TextView(txt)只有100的值?

UPD: 此代码不起作用

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

    final MyViewHolder holder = new MyViewHolder(itemView);

    itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = holder.getAdapterPosition();
            if (position != RecyclerView.NO_POSITION) {
                File source = new File(imgs.get(position).getFilepath());
                String strFileName = source.getName();
                File destination = new File("My path" + "/" + strFileName);

                try {
                    InputStream input = null;
                    OutputStream output = null;
                    long lenghtOfFile = source.length();
                    int count;
                    try {
                        input = new FileInputStream(source);
                        output = new FileOutputStream(destination);
                        byte[] data = new byte[1024];
                        long total  = 0;
                        int xc2 = 0;
                        while ((count = input.read(data)) != -1) {
                            total += count;
                            int xc = (int) ((total * 100) / lenghtOfFile);
                            output.write(data, 0, count);
                            if (xc2!=xc){
                                //holder.progress_bar.setProgress(xc);
                                imgs.get(position).setProgress(xc);
                                notifyItemChanged(position);
                                try {
                                    Thread.sleep(40);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            xc2 = xc;
                        }
                    } finally {
                        output.flush();
                        output.close();
                        input.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });

    return holder;
}

UPD2: 此代码不起作用

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

    final MyViewHolder holder = new MyViewHolder(itemView);

    itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = holder.getAdapterPosition();
            if (position != RecyclerView.NO_POSITION) {
                for (int i=1; i<=100; ++i) {
                    imgs.get(position).setProgress(i);
                    notifyItemChanged(position);
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    });

    //return new MyViewHolder(itemView);
    return holder;
}

1 个答案:

答案 0 :(得分:2)

基本上你在UI线程上加载你的文件,所以每当你调用notifyItemChanged()时,你都会向Looper添加一个任务,但只有当你完成加载时,Looper才会进入该任务因此,你只能看到100。

我会在不同的线程上运行负载,如下所示:

new View.OnClickListener() {
        @Override
        public void onClick(View view) {
           File source = new File(imgs.get(position).getFilepath());
           String strFileName = source.getName();
           File destination = new File("My path" + "/" + strFileName);
           **> Thread t1 = new Thread(new Runnable(){
           public void run(){ <**
           try {
               InputStream input = null;
               OutputStream output = null;
               long lenghtOfFile = source.length();
               int count;
               try {
                   input = new FileInputStream(source);
                   output = new FileOutputStream(destination);
                   byte[] data = new byte[1024];
                   long total  = 0;
                   int xc2 = 0;
                   while ((count = input.read(data)) != -1) {
                      total += count;
                      int xc = (int) ((total * 100) / lenghtOfFile);

                      output.write(data, 0, count);
                      imgs.get(position).setProgress(xc);
                      notifyItemChanged(position);
                      try {
                          Thread.sleep(20);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              } finally {
               output.flush();
               output.close();
               input.close();
              }
        } catch (IOException e) {
           e.printStackTrace();
        }
      } 
     t1.start();
    }
}

我的猜测,祝你好运!