在我們Android 開發(fā)中低散,ListView是在常用不過的控件了婆瓜。但是有時(shí)候會(huì)爆出這種異常苔严,就搞得好尷尬了每瞒。
明明我們?cè)诖a中的確是有調(diào)用adaptor.notifyDataSetChanged()這個(gè)方法的,明顯沒問題啊暇唾。
后來我查代碼促脉,才發(fā)現(xiàn),在我們更新過程中大部分使用到的是異步操作策州,但是如果網(wǎng)絡(luò)很卡瘸味,然后又發(fā)出了大量的請(qǐng)求的話,那么就會(huì)出現(xiàn)這個(gè)問題够挂。要怎么解決這個(gè)問題呢旁仿?
這是代碼
import java.util.ArrayList;
import java.util.List;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
/**
* @author 肖蕾
* @param <DataType>
* 傳入的數(shù)據(jù)類型
* @param <viewHolder>
* ViewHoler的類型
*/
public abstract class BaseAdapter<DataType, viewHolder extends BaseAdapter.Holder> extends android.widget.BaseAdapter
{
/**
* 保存的數(shù)據(jù)
*/
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 的創(chuàng)建
*
* @param parent
* 父控件
* @param viewType
* 類型
* @return
*/
public abstract viewHolder onCreateViewHolder(ViewGroup parent, int viewType);
/**
* ViewHolder與數(shù)據(jù)的綁定
*
* @param holder
* viewHoler對(duì)象
* @param data
* 數(shù)據(jù)
* @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);
}
/**
* 新建一個(gè)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與數(shù)據(jù)綁定
*/
@Override
public void onBindViewHolder(Holder holder, String data, int position)
{
TextView text = holder.get(R.id.text);
text.setText(data);
}
}
原理
原理是什么呢?我們?cè)赼daptor內(nèi)部就封裝了一個(gè)List用于保存用戶傳過來的List數(shù)據(jù)孽糖,我們這里只是對(duì)外部的list有一個(gè)引用枯冈,但是真正使用到的list,卻是內(nèi)部的List,通過每一次調(diào)用notifyDataSetChanged()方法办悟,則自動(dòng)將內(nèi)部的list數(shù)據(jù)與外部的list數(shù)據(jù)同步一次尘奏。再調(diào)用父類的更新、這樣病蛉,我們玩來玩去就是外部的list炫加,并不會(huì)對(duì)內(nèi)部listview使用到的list有任何影響瑰煎。就完美屏蔽了這個(gè)異常了。
另外
分享一句我最喜歡的歌詞:
如果那兩個(gè)字沒有顫抖
我不會(huì)發(fā)現(xiàn)我難受
怎么說出口也不會(huì)是分手如果對(duì)于明天沒有要求
牽牽手就像旅游(女友)
成千上萬(wàn)個(gè)門口
總有一個(gè)人要先走懷抱既然不能逗留
何不在離開的時(shí)候
一邊享受一邊淚流