100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > android listview item 错位 Android BaseAdapter和ViewHolder 优化 解决ListV

android listview item 错位 Android BaseAdapter和ViewHolder 优化 解决ListV

时间:2023-02-24 22:10:36

相关推荐

android listview item 错位 Android BaseAdapter和ViewHolder 优化 解决ListV

首先赞下hyman大神

曾经仅仅是简单的重写个BaseAdapter,将getView方法保持抽象。而ViewHolder没有抽象过。

。。

ViewHolder (用了一个集合+泛型管理存取view)

/**

* author : stone

* email : [emailprotected]

* 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; //更新复用的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();

}

/*------------------------ 设置view属性(以后扩展) --------------------------------*/

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 : [emailprotected]

* 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) {

}

});

}

};

关于Adapter中View抢焦点:

假设 listView.setOnItemClickListener(listener); 且item中的 button.setOnClickListener(listener);

无论怎么点击,button会一直被触发...

仅仅须要在item的root-layout中 加入 一个属性: android:descendantFocusability="blocksDescendants"

关于item-view复用后。显示混乱:

有时条目过多,滑动到下一屏数据时。有些view复用后,view的状态(比方CheckBox的选种状态。ImageView的图片反复出现)会变乱。

一般处理呢。须要有一个机制,来管理一种相应关系: 当前position相应哪种状态

比方说checkBox选中状态混乱:

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);//记录状态。防缓存显示

}

});

cb.setChecked(isChecked(position));

}

}

关于SparseArray

SparseArray 内部实现是Array数组。当长度不够时,会调用System.arrayCopy

内部有 keys和values两个数组。

put(key, value); 二分法查找key应该存放的位置 由于key是Integer类型

put、get时 两个数组都是操作的同一个位置上的数据

SparseArray 用于替代形如 HashMap

SparseBooleanArray 用于替代形如 HashMap

SparseIntArray 用于替代形如 HashMap

SparseLongArray 用于替代形如 HashMap

support.v4.util.SparseArrayCompat 提供了v4包相应平台的 SparseArray实现

android listview item 错位 Android BaseAdapter和ViewHolder 优化 解决ListView的item抢焦点问题和item错乱问题...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。