在咱们Android 开发中,ListView是在经常使用不过的控件了。可是有时候会爆出这种异常,就搞得好尴尬了。
明明咱们在代码中的确是有调用adaptor.notifyDataSetChanged()这个方法的,明显没问题啊。 后来我查代码,才发现,在咱们更新过程当中大部分使用到的是异步操做,可是若是网络很卡,而后又发出了大量的请求的话,那么就会出现这个问题。要怎么解决这个问题呢?java
#这是代码android
import java.util.ArrayList; import java.util.List; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; /** * @author 肖蕾 * @param <DataType> * 传入的数据类型 * @param <viewHolder> * ViewHoler的类型 */ public abstract class BaseAdapter<DataType, viewHolder extends BaseAdapter.Holder> extends android.widget.BaseAdapter { /** * 保存的数据 */ private List<DataType> list = new ArrayList<DataType>(); private List<DataType> outer_list; public BaseAdapter(List<DataType> list) { this.outer_list = list; this.list.addAll(outer_list); } @Override public int getCount() { return getItemCount(); } @Override public DataType getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public void notifyDataSetChanged() { this.list.clear(); this.list.addAll(outer_list); super.notifyDataSetChanged(); } /** * View 的建立 * * @param parent * 父控件 * @param viewType * 类型 * @return */ public abstract viewHolder onCreateViewHolder(ViewGroup parent, int viewType); /** * ViewHolder与数据的绑定 * * @param holder * viewHoler对象 * @param data * 数据 * @param position * 定位 */ public abstract void onBindViewHolder(viewHolder holder, DataType data, int position); public int getItemCount() { if (list == null) { return 0; } return list.size(); } public int getItemViewType(DataType data, int position) { return super.getItemViewType(position); } @SuppressWarnings("unchecked") @Override public View getView(int position, View convertView, ViewGroup parent) { viewHolder holder = null; DataType data = list.get(position); if (convertView == null) { holder = onCreateViewHolder(parent, getItemViewType(data, position)); convertView = holder.getRootView(); } else { holder = (viewHolder) convertView.getTag(); } onBindViewHolder(holder, data, position); return convertView; } public static class Holder { private View root; private SparseArray<View> store = new SparseArray<View>(); @SuppressWarnings("unchecked") public <T extends View> T get(int id) { View result = store.get(id); if(result == null) { result = root.findViewById(id); store.append(id, result); } return (T) result; } public Holder(View view) { this.root = view; } public View getRootView() { root.setTag(this); return root; } } }
#使用方法网络
public class mAdapter extends BaseAdaptor<String, BaseAdaptor.Holder> { public mAdapter(List<String> list) { super(list); } /** * 新建一个ViewHoler */ @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = View.inflate(parent.getContext(), R.layout.item, null); Holder holder = new Holder(view); return holder; } /** * ViewHoler与数据绑定 */ @Override public void onBindViewHolder(Holder holder, String data, int position) { TextView text = holder.get(R.id.text); text.setText(data); } }
#原理app
原理是什么呢?咱们在adaptor内部就封装了一个List用于保存用户传过来的List数据,咱们这里只是对外部的list有一个引用,可是真正使用到的list,倒是内部的List,经过每一次调用notifyDataSetChanged()方法,则自动将内部的list数据与外部的list数据同步一次。再调用父类的更新、这样,咱们玩来玩去就是外部的list,并不会对内部listview使用到的list有任何影响。就完美屏蔽了这个异常了。异步
#另外ide
分享一句我最喜欢的歌词: 若是那两个字没有颤抖 我不会发现我难受 怎么说出口也不会是分手this
若是对于明天没有要求 牵牵手就像旅游(女朋友) 成千上万个门口 总有一我的要先走code
怀抱既然不能逗留 何不在离开的时候 一边享受一边泪流对象