问题发现
需求:在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);
}
}
}
}