ListView 使用总结

2017-02-28  本文已影响54人  三十二蝉

ListView常用属性

自定义Adapter基类

直接继承BaseAdapter会需要实现很多函数,这个写了一个抽象类SimpleBaseAdapter,使用时继承SimpleBaseAdapter会减少开发量
SimpleBaseAdapter.java:

 public abstract class SimpleBaseAdapter<T> extends BaseAdapter {

    protected Context mContext;
    protected List<T> data;

    public SimpleBaseAdapter(Context context,List<T> data){
        this.mContext = context;
        this.data = data == null?new ArrayList<T>():new ArrayList<T>(data);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        if(position >= data.size()){
            return null;
        }
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 该方法需要子类实现,需要返回item布局的resource id
     *
     * @return
     */
    public abstract int getItemResource(int position);

    /**
     * 使用该getItemView方法替换原来的getView方法,需要子类实现
     *
     * @param position
     * @param convertView
     * @param holder
     * @param isInitializeConvertView
     * @return
     */
    public abstract View getItemView(int position, View convertView, ViewHolder holder,boolean isInitializeConvertView );

    @SuppressWarnings("unchecked")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        boolean isInitializeConvertView = false;
        if(null == convertView){
            isInitializeConvertView =true;
            convertView = LayoutInflater.from(mContext).inflate(getItemResource(position), parent, false);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        return getItemView(position,convertView,viewHolder,isInitializeConvertView);
    }

    public void addAll(List<T> elem) {
        data.addAll(elem);
        notifyDataSetChanged();
    }

    public void remove(T elem) {
        data.remove(elem);
        notifyDataSetChanged();
    }

    public void remove(int index) {
        data.remove(index);
        notifyDataSetChanged();
    }

    public void replaceAll(List<T> elem) {
        data.clear();
        data.addAll(elem);
        notifyDataSetChanged();
    }

    public class ViewHolder {
        private SparseArray<View> views = new SparseArray<View>();
        private View convertView;
        private Object[] holderObjs;

        public ViewHolder(View convertView) {
            this.convertView = convertView;
        }

        @SuppressWarnings("unchecked")
        public <T extends View> T getView(int resId) {
            View v = views.get(resId);
            if (null == v) {
                v = convertView.findViewById(resId);
                views.put(resId, v);
            }
            return (T) v;
        }

        public Object[] getHolderObjs() {
            return holderObjs;
        }

        public void setHolderObjs(Object[] holderObjs) {
            this.holderObjs = holderObjs;
        }
    }

}

1)规范化数据源~~ 有些人用Adapter比较随意,有时候Adapter里面还附带了数据解析的功能(传进Adapter的可能是JsonArray,可能直接是String类型的response)。这里规范了数据源,Adapter里面不做数据解析的工作。采用泛型编程,子类继承的时候,指定数据类型就可以直接使用了。
2)添加了一些操作数据源的方法。包括addAll,replaceAll,remove等方法,方便数据更新。
3)内部持有一个viewHolder对象。viewHolder对象有两个功能:
1、避免重复的findViewById的过程
2、在viewHolder实例上可以绑定一些数据,或者标志位

应用实例:

 private class IndexAdapter extends SimpleBaseAdapter<DatalineWordsModel>{

        public IndexAdapter(Context context,List<DatalineWordsModel> list){
            super(context,list);
        }


        @Override
        public int getItemResource(int position) {
            return R.layout.dataline_words_index_item;
        }

        @Override
        public View getItemView(int position, View convertView, ViewHolder holder, boolean isInitializeConvertView) {
            TextView words = (TextView) convertView.findViewById(R.id.classical_dataline_words_words);
            words.setText(data.get(position).words);
            Object[] objs = new Object[1];
            objs[0] = position;
            holder.setHolderObjs(objs);
            convertView.setOnClickListener(indexClick);
            return convertView;
        }
    }

ListView使用中会碰到的问题

告诉listview当前位置的data对应那种布局

  @Override
     public int getViewTypeCount() {
         return 2;
     }

告诉listv总共有多少种布局类型

@Override
     public int getItemResource(int position) {
         return data.get(position).getType() == title?R.layout
                 .dataline_detail_item_title:R.layout.dataline_detail_item_content;
     }

根据类型实例化不同的布局文件

   @Override
    public void setAdapter(ListAdapter adapter) {
        if (mAdapter != null && mDataSetObserver != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        }

        resetList();
        mRecycler.clear();

        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }

        mOldSelectedPosition = INVALID_POSITION;
        mOldSelectedRowId = INVALID_ROW_ID;

        // AbsListView#setAdapter will update choice mode states.
        super.setAdapter(adapter);

        if (mAdapter != null) {
            mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
            mOldItemCount = mItemCount;
            mItemCount = mAdapter.getCount();
            checkFocus();

            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);

            mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());

            int position;
            if (mStackFromBottom) {
                position = lookForSelectablePosition(mItemCount - 1, false);
            } else {
                position = lookForSelectablePosition(0, true);
            }
            setSelectedPositionInt(position);
            setNextSelectedPositionInt(position);

            if (mItemCount == 0) {
                // Nothing selected
                checkSelectionChanged();
            }
        } else {
            mAreAllItemsSelectable = true;
            checkFocus();
            // Nothing selected
            checkSelectionChanged();
        }

        requestLayout();
    }

listview的setAdapter方法中有一句:

  mRecycler.clear();

这个就可以把convertview缓存删除。所有只需要listview把同一个Adapter实例装载进来就行了。

上一篇下一篇

猜你喜欢

热点阅读