我有一个列表视图,项目有一个图像按钮和一个ProgressBar。
我从Thread中更新ProgressBar(进度集)。
每当调用列表适配器中的getView时,列表视图项都将被实例化 并且对ProgressBar的引用将会改变。所以我将ProgressBar的最后一个引用放在适配器的HashMap中,当我想更新ProgressBar时,我将它用作最后一个引用。
但它根据项目数量的不同而有所不同。当项目的大小太多而列表视图处于滚动模式时它可以正常工作但是有一个或两个项目适合一页而不滚动,ProgressBar会卡住但是选择一个项目,ProgressBar继续没有问题。
似乎在最后的getView和下一个notifyDataSetChanged()可能是由列表选择或滚动引起的,ProgressBar的引用已经改变了getView()所以我不能拥有最后一个(或者不,我不知道!)。
我还在每个setProgress上尝试过notifyDataSetChanged(),但效率不高,还会阻塞imageButton OnClickListener。
这是适配器代码:
public class ChatAdapter extends BaseAdapter {
private List<Message> messagesItems;
private Map<Message,ProgressWheel> ProgressBars =new HashMap<>();//to have last reference to the ProgressBar corresponding to each listItem
public Map<Message,Boolean> showProgress=new HashMap<>();//for some controlling
public Map<Message,Boolean> active=new HashMap<>();//for some controlling
public Map<Message,View> layouts=new HashMap<>();//for some controlling
public Map<Message,View> views=new HashMap<>();//for some controlling
final static android.os.Handler mHandler=new android.os.Handler();
@SuppressLint("InflateParams")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Message currentMessage = (Message) getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final ViewHolder viewHolder;
if(convertView==null) {
convertView = mInflater.inflate(R.layout.chat_row_right, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}else {
viewHolder=(ViewHolder) convertView.getTag();
}
ImageButton sendButton= viewHolder.SkipButton;
View progressLayout= convertView.findViewById(R.id.proressLayout);
//ProgressWheel is a custom progressBar
ProgressWheel progressWheel = viewHolder.progressBar;
ProgressBars.put(currentMessage, progressWheel);
layouts.put(currentMessage,progressLayout);
views.put(currentMessage, convertView);
if(showProgress.get(currentMessage)!=null) {
if (showProgress.get(currentMessage)) {
progressLayout.setVisibility(View.VISIBLE);
sendButton.setTag(currentMessage);
//ProgressBarHandler.start just runs a thread and increments progress in background by calling setDelayProgress from this class
if (active.get(currentMessage) == null) {
active.put(currentMessage, true);
ProgressBarHandler progressBarHandler = new ProgressBarHandler(currentMessage, this,this);
progressBarHandler.start(10);
notifyDataSetChanged();
} else if (active.get(currentMessage) == false) {
active.put(currentMessage, true);
ProgressBarHandler progressBarHandler = new ProgressBarHandler(currentMessage, this,this);
progressBarHandler.start(10);
notifyDataSetChanged();
}
} else {
progressLayout.setVisibility(View.GONE);
}
}else
progressLayout.setVisibility(View.GONE);
return convertView;
}
public void setDelayProgress(final Message message, final int progress, final long durationMillis){
mHandler.post(new Runnable() {
@Override
public void run() {
ProgressBars.get(message).setProgress(progress);
// notifyDataSetChanged();// is cause the code extremely inefficient But working !
}
});
}
final static class ViewHolder {
public TextView message;
public ProgressWheel progressBar;
public ImageButton SkeepButton;
public ViewHolder(View convertView){
this.message = (TextView) convertView
.findViewById(R.id.chatMessage);
this.progressBar = (ProgressWheel) convertView
.findViewById(R.id.delayProgress);
this.SkeepButton = (ImageButton) convertView
.findViewById(R.id.sendb);
}
}
}
您的建议将不胜感激,谢谢