android listview item 错位,Android BaseAdapter和ViewHolder 优化 解决ListView的item抢焦点问题和item错乱问题...
首先贊下hyman大神
曾經(jīng)僅僅是簡單的重寫個BaseAdapter,將getView方法保持抽象。而ViewHolder沒有抽象過。
。。
ViewHolder (用了一個集合+泛型管理存取view)
/**
* author : stone
* email : [email?protected]
* time : 15/7/24 14 27
*/
public class StoneViewHolder {
private int mPosition;
private View mConvertView;
private SparseArray mViews; //管理listView-item中的view
public StoneViewHolder(Context context, int layoutId, int position, ViewGroup parent) {
this.mPosition = position;
this.mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
this.mConvertView.setTag(this);
this.mViews = new SparseArray();
}
public View getConvertView() {
return mConvertView;
}
public static StoneViewHolder getInstance(Context context, int layoutId, int position, View
convertView, ViewGroup parent) {
if (convertView == null) {
return new StoneViewHolder(context, layoutId, position, parent);
} else {
StoneViewHolder holder = (StoneViewHolder) convertView.getTag();
holder.mPosition = position; //更新復(fù)用的convertView中 position
return holder;
}
}
public T getView(int viewId) {
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}
public void setTag(int viewId, T tag) {
getView(viewId).setTag(tag);
}
public T getTag(int viewId) {
return (T) getView(viewId).getTag();
}
/*------------------------ 設(shè)置view屬性(以后擴(kuò)展) --------------------------------*/
public StoneViewHolder setText(int viewId, String text) {
((TextView)getView(viewId)).setText(text);
return this;
}
public StoneViewHolder setText(int viewId, int resId) {//R.string.
((TextView)getView(viewId)).setText(resId);
return this;
}
public StoneViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
((ImageView)getView(viewId)).setImageBitmap(bitmap);
return this;
}
public StoneViewHolder setImageResource(int viewId, int resId) {
((ImageView)getView(viewId)).setImageResource(resId);
return this;
}
}
Adapter
/**
* author : stone
* email : [email?protected]
* time : 15/7/24 14 46
*/
public abstract class StoneListAdapter extends BaseAdapter {
private List mData;
private Context mContext;
private int mLayoutID;
public StoneListAdapter(Context context, int layoutID, List data) {
this.mContext = context;
this.mLayoutID = layoutID;
this.mData = data == null ? new ArrayList() : data;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public T getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
StoneViewHolder holder = StoneViewHolder.getInstance(mContext, mLayoutID, position,
convertView, parent);
getView(mContext, holder, position);
return holder.getConvertView();
}
protected abstract void getView(Context context, StoneViewHolder holder, int position);
}
在ListViewActivity中使用
stoneBaseAdapter = new StoneListAdapter(ListViewActivity.this, R.layout.activity_listview_item, mData) {
@Override
protected void getView(Context context, final StoneViewHolder holder, final int position) {
User user = getItem(position);
holder.setText(R.id.tv_id, user.getId()).setText(R.id.tv_name, user.getName())
.setText(R.id.tv_age, user.getAge() + "");
holder.getView(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
};
關(guān)于Adapter中View搶焦點(diǎn):
假設(shè) listView.setOnItemClickListener(listener); ? 且item中的 ?button.setOnClickListener(listener);
無論怎么點(diǎn)擊,button會一直被觸發(fā)...
僅僅須要在item的root-layout中 加入 一個屬性: ??android:descendantFocusability="blocksDescendants"
關(guān)于item-view復(fù)用后。顯示混亂:
有時條目過多,滑動到下一屏數(shù)據(jù)時。有些view復(fù)用后,view的狀態(tài)(比方CheckBox的選種狀態(tài)。ImageView的圖片反復(fù)出現(xiàn))會變亂。
一般處理呢。須要有一個機(jī)制,來管理一種相應(yīng)關(guān)系: 當(dāng)前position相應(yīng)哪種狀態(tài)
比方說checkBox選中狀態(tài)混亂:
class MyAdapter extends StoneListAdapter {
private SparseBooleanArray mCheckStateArray;
public MyAdapter(Context context, int layoutID, List data) {
super(context, layoutID, data);
this.mCheckStateArray = new SparseBooleanArray();
}
public void setChecked(int position, boolean isChecked) {
mCheckStateArray.put(position, isChecked);
}
public boolean isChecked(int position) {
return mCheckStateArray.get(position);
}
@Override
protected void getView(Context context, final StoneViewHolder holder, final int position) {
CheckBox cb = holder.getView(R.id.cb_check);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
setChecked(position, isChecked);//記錄狀態(tài)。防緩存顯示
}
});
cb.setChecked(isChecked(position));
}
}
關(guān)于SparseArray
SparseArray 內(nèi)部實現(xiàn)是Array數(shù)組。當(dāng)長度不夠時,會調(diào)用System.arrayCopy
內(nèi)部有 keys和values兩個數(shù)組。
put(key, value); 二分法查找key應(yīng)該存放的位置 ?由于key是Integer類型
put、get時 兩個數(shù)組都是操作的同一個位置上的數(shù)據(jù)
SparseArray 用于替代形如 ?HashMap
SparseBooleanArray 用于替代形如 ?HashMap
SparseIntArray 用于替代形如 ?HashMap
SparseLongArray 用于替代形如 ?HashMap
support.v4.util.SparseArrayCompat 提供了v4包相應(yīng)平臺的 SparseArray實現(xiàn)
總結(jié)
以上是生活随笔為你收集整理的android listview item 错位,Android BaseAdapter和ViewHolder 优化 解决ListView的item抢焦点问题和item错乱问题...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android bitmap保存本地图片
- 下一篇: android比较常用的布局,Andro