当前位置: 代码迷 >> Android >> Android BaseAdapter跟ViewHolder 优化
  详细解决方案

Android BaseAdapter跟ViewHolder 优化

热度:387   发布时间:2016-04-27 23:49:22.0
Android BaseAdapter和ViewHolder 优化

首先赞下hyman大神

以前只是简单的重写个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<View> 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<View>();    }    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 extends View>  T getView(int viewId) {        View view = mViews.get(viewId);        if (view == null) {            view = mConvertView.findViewById(viewId);            mViews.put(viewId, view);        }        return (T) view;    }    public <T> void setTag(int viewId, T tag) {        getView(viewId).setTag(tag);    }    public <T> 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  : [email protected] * time   : 15/7/24 14 46 */public abstract class StoneListAdapter<T> extends BaseAdapter {    private List<T> mData;    private Context mContext;    private int mLayoutID;    public StoneListAdapter(Context context, int layoutID, List<T> data) {        this.mContext = context;        this.mLayoutID = layoutID;        this.mData = data == null ? new ArrayList<T>() : 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<User>(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<User> {        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));        }    }





版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案