在咱們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
懷抱既然不能逗留 何不在離開的時候 一邊享受一邊淚流對象