Adapter内使用线程修改ProgressBar。

线程内ProgressBar的修改

问题发现

需求:在RecycleerView中的item,每一个item都想建立一个进度条,在线程内,来实现这一个item的下载情况。
所以就在item内增加了ProgressBar,但是像往常一下将组件放在ViewHolder类下面,发现在覆写onBindBiewHolder时。
定义的handler内,无法修改ProgressBar.

问题定位

利用download_ProgressBar.getVisibility()方法,去看是否handler内的holder.download_ProgressBar无法得到正确的对象。
最终发现,handler内的对象和直接使用holder.的对象是不同的。所以问题在于,无法得到正确的对象。
onBindViewHolder内新建的Handler对象无法得到正确的holder.download_ProgressBar.

  @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
Handler DownloadHandler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {
                if (msg.what < 100) {
                    Toast.makeText(context,"正在下载",Toast.LENGTH_SHORT).show();
                    holder.download_ProgressBar.setVisibility(View.VISIBLE);
                    Log.d("TrainModeAdapter", "handleMessage: 正在下载:"+msg.what+"visibility:"+holder.download_ProgressBar.getVisibility());
                }else{
                    switch (msg.what){
                        case 8001:
                            holder.download_ProgressBar.setVisibility(View.INVISIBLE);
                            Log.d("TrainModeAdapter", "handleMessage: 正在下载:"+msg.what+"visibility:"+holder.download_ProgressBar.getVisibility());
                            Toast.makeText(context,"下载完成",Toast.LENGTH_LONG).show();
                            Log.d("TrainModeAdapter", "下载完成");
                    }
                }
                return false;
            }
           }
        });

实现

为什么别的TextView或者image都是没有问题的,对于其他控件是可以去正确的找到对应的。在别的博客上,大概可以找到一些答案,ProgressBar的源码跟上下文有关。
所以会造成这样的一个问题,但是问题根源在哪里,我确实不是很清楚。希望有大神能解答一番。
具体解决方法:在类中建立一个静态变量,将静态变量赋值到ViewHolder类中,但在ViewHolder方法中绑定的是静态变量。
所以在onBinderViewHolder中handler内改变的就可以是这个静态变量。
想peach吧,在Adapter内获取不到对应item值,所以handler放在Adapter内,不知道怎么实现。。
所以还是乖乖的把Handler放到activity外面.
利用
View itemview = TrainMode_recycleview.findViewHolderForAdapterPosition(Position).itemView;
ProgressBar download_ProgressBar = itemview.findViewById(R.id.TrainMode_ProgressBar);

然后构造函数去传入这个Handler即可。。。

public class TrainModeAdapter extends RecyclerView.Adapter<TrainModeAdapter.ViewHolder> {
    DownloadStreamThread DownloadStreamThread_item;
    private static ProgressBar Download_ProgressBar;
    private Handler xxHandler;
     public TrainModeAdapter(Handler handler){
     this.xxHandler = handler;
     }
     
       static class ViewHolder extends RecyclerView.ViewHolder{
               private ProgressBar download_ProgressBar = Download_ProgressBar;
       }
            public ViewHolder(View view){
            super(view);
            Download_ProgressBar =view.findViewById(R.id.TrainMode_ProgressBar);
        }
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
		//设置Handler
        DownloadStreamThread_item.setDownloadHandler(xxHandler);
}


    public class DownloadStreamThread extends Thread {
        String urlStr;
        String targetFileAbsPath;
        Handler DownloadHandler;
        public DownloadStreamThread(String urlStr, String targetFileAbsPath) {
            this.urlStr = urlStr;
            this.targetFileAbsPath = targetFileAbsPath;
            Log.d(TAG, "urlStr: :"+urlStr);
            Log.d(TAG, "targetFileAbsPath: :"+targetFileAbsPath);
        }
        public String GetDownloadAbsPath(){
            return targetFileAbsPath;
        }
        public void setDownloadHandler (Handler downloadHandler){
            this.DownloadHandler = downloadHandler;
        }

        @Override
        public void run() {
            super.run();
            int count;
            try {
                URL url = new URL(urlStr);
                URLConnection connection = url.openConnection();
                connection.connect();
                String FileName = null;
                URL url2 = connection.getURL();// 获得实际下载文件的URL
                String file1 = url2.getFile();
                FileName = file1.substring(file1.lastIndexOf("/") + 1);
                this.targetFileAbsPath = targetFileAbsPath+FileName;
                Log.d(TAG, "fileName:dirctor"+targetFileAbsPath);
                File targetFile = new File(targetFileAbsPath);
                if (targetFile.exists())
                {
                    //就直接播放
                    targetFile.delete();
                }else {
                try {
                    boolean n = targetFile.createNewFile();
                    Log.d(TAG, "Create new file: " + n + ", " + targetFile);
                    if (n){
                        int contentLength = connection.getContentLength();
                        InputStream input = new BufferedInputStream(url.openStream());
                        OutputStream output = new FileOutputStream(targetFileAbsPath);
                        byte[] buffer = new byte[1024];
                        long total = 0;
                        Message msg = new Message();
                        msg.what = 1;
                        this.DownloadHandler.sendMessage(msg);
                        while ((count = input.read(buffer)) != -1) {
                            total += count;
                            Log.d(TAG, String.format(Locale.CHINA, "Download progress: %.2f%%", 100 * (total / (double) contentLength)));
                            output.write(buffer, 0, count);
                            if (total == contentLength){
                                Log.d(TAG, "下载完成");
                                Message msg_done = new Message();
                                msg_done.what = 8001;
                                this.DownloadHandler.sendMessage(msg_done);
                            }else{
                                //下载失败,删除文件,并发消息
                            }
                        }
                        output.flush();
                        output.close();
                        input.close();
                    }else{
                        Log.d(TAG, "Create new file: " + n +":创建文件失败");
                    }
                } catch (IOException e) {
                    Log.e(TAG, "run: ", e);
                }}
            } catch (Exception e) {
                Log.e(TAG, "run: ", e);
            }
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值