最可能出现重复的情况就是getView(int position, View convertView, ViewGroup parent)中的convertview利用的情况,由于getview的时候,listview自身会复用已存在的item,即重用最先新建的那几个item,还有就是注意tag的使用,convertView.getTag()返回的也是重用的view,其状态是和被重用的一样,包括图片的显示与隐藏的状态,进度条的刷新等,都会被重用,这就出现了图片或者进度条错乱的情况,这时就需要在getview的时候,先把状态复原(即隐藏进度条,去掉没有下载的item的监听,图片设为默认等等),然后再根据判断条件修改各个item的状态。
ListView只会缓存第一屏里面的List Item的视图布局,之后滚动ListView后面的Item的布局就都是用前面所缓存的视图布局(也就是convertView不为null)。这样如果当后面的某一条记录里面的某些控件因上面的原因没有赋值,就会直接使用前面所缓存的视图里面的值了(里面有值的话)。
这样的最终效果就是,滚动的时候,会出现前面已经出现过的内容。
解决办法就是用setTag();
public class NursingProjectAdapter extends BaseAdapter {
private static final String TAG = NursingProjectAdapter.class.getSimpleName();
private Context mContext;
private LayoutInflater mLayoutInflater;
private List<NursingProject> mNps;
private ListView mListView;
/**
* 存储CheckBox选中记录
*/
public Map<Integer, Boolean> isSelected;
/**
* 存储扫描患者腕带标签执行所勾选的护理项目成功的数据
* key 代表扫描患者腕带标签
* value 代表扫描患者腕带标签时所勾选的护理项目,这些勾选的护理项目是已经执行成功的
*/
private Map<String,ArrayList<String>> cacheSubCodeMap = new HashMap<String, ArrayList<String>>();
/**
* 勾选的项目
*/
private ArrayList<String> cacheSelectItems;
/**
* 扫描的患者腕带标签
*/
private String selectItem;
public NursingProjectAdapter(Context context,List<NursingProject> nps,String mSelectItem){
this.mContext = context;
this.mLayoutInflater = LayoutInflater.from(context);
this.mNps = nps;
this.selectItem = mSelectItem;
initMapAboutCheckBox();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mNps.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mNps.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
convertView = this.mLayoutInflater.inflate(R.layout.listitem_care_to_perfromnew, null);
holder = new ViewHolder();
holder.cbPerfroms = (CheckBox) convertView.findViewById(R.id.cbPerfroms);
holder.tvPerfromsStatus = (TextView) convertView.findViewById(R.id.tvPerfromsStatus);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.tvPerfromsStatus.setText(mNps.get(position).getSubitemName());
//给tvPerfromsStatus控件做一个标记,防止listview向下滚动时,出现各项背景色错乱
holder.tvPerfromsStatus.setTag(mNps.get(position).getSubitemCode());
//给cbPerfroms控件做一个标记,防止listview向下滚动时,勾选的checkbox出现错乱
holder.cbPerfroms.setTag(position);
if(!isSelected.isEmpty()){
holder.cbPerfroms.setChecked(isSelected.get(position));
}
//若包含,根据已经执行过的记录是否包含,包含则变为绿色,不包含则为默认背景色
if(cacheSubCodeMap.containsKey(selectItem)){
if(holder.tvPerfromsStatus.getTag() != null){
if(cacheSubCodeMap.get(selectItem).contains(holder.tvPerfromsStatus.getTag())){ //包含,根据标记唯一确保滚动时背景色不会错乱
convertView.setBackgroundColor(mContext.getResources().getColor(
R.color.green));
}else{ //不包含,默认背景色
convertView.setBackgroundColor(mContext.getResources().getColor(
R.color.day_blue));
}
}
}else{ //首次渲染listview或非首次渲染,不包含没有扫描过的标签,各项默认背景色
if(holder.tvPerfromsStatus.getTag() != null && holder.tvPerfromsStatus.getTag().equals(mNps.get(position).getSubitemCode())){
convertView.setBackgroundColor(mContext.getResources().getColor(
R.color.day_blue));
}
}
return convertView;
}
public class ViewHolder{
public CheckBox cbPerfroms;
public TextView tvPerfromsStatus;
}
public List<NursingProject> getmNps() {
return mNps;
}
public void setmNps(List<NursingProject> mNps) {
this.mNps = mNps;
}
public Map<Integer, Boolean> getIsSelected() {
return isSelected;
}
public void setIsSelected(Map<Integer, Boolean> isSelected) {
this.isSelected = isSelected;
}
public Map<String, ArrayList<String>> getCacheSubCodeMap() {
return cacheSubCodeMap;
}
/**
* 初始化checkbox选中状态
* @param mNps
*/
public void initMapAboutCheckBox(){
isSelected = new HashMap<Integer, Boolean>();
if(mNps != null && mNps.size() > 0){
for (int i = 0; i < mNps.size(); i++) {
isSelected.put(i, false);
}
}
}
/**
* 扫描患者腕带标签,执行勾选的项目记录成功时存储数据
* @param selectItem 扫描的患者腕带标签
* @param subCode 勾选的项目ID
*/
public void setSelectItem(String selectItem,String subCode) {
this.selectItem = selectItem;
if(cacheSubCodeMap.containsKey(selectItem)){
cacheSubCodeMap.get(selectItem).add(subCode);
}else{
cacheSelectItems = new ArrayList<String>();
cacheSelectItems.add(subCode);
cacheSubCodeMap.put(selectItem, cacheSelectItems);
}
}
/**
* 获取已经选中的项数据
* @author chixianpeng
* @date 2015-8-6 15:09
* @return
*/
public List<NursingProject> getSelectedItem(){
List<NursingProject> selectedItemList = new ArrayList<NursingProject>();
for (int i = 0; i < mNps.size(); i++) {
if(isSelected.containsKey(i)){
boolean isSelect = isSelected.get(i);
if(isSelect){ //已经选中的
NursingProject np = mNps.get(i);
selectedItemList.add(np);
}
}
}
return selectedItemList;
}
}
//执行成功通知adapter更新勾选的项改变背景色为绿色
mNursingProjectAdapter.setSelectItem(mPrintCode, np.getSubitemCode());
mNursingProjectAdapter.notifyDataSetChanged();