美文网首页
ListView 使用总结

ListView 使用总结

作者: 三十二蝉 | 来源:发表于2017-02-28 18:05 被阅读54次

    ListView常用属性

    • android:listSelector
      listview中item选中的背景变化,希望背景不变化,可以设置为 android:listSelector="#00000000"

    • android:overScrollMode
      listview默认第一个item还可以往下拉,会拉出一块空白;想禁用这个功能,可以把overScrollMode属性设为never

    • android:divider
      设置item之间分隔线样式,可自定义;"@null"为禁用

    • android:scrollbars
      设置滚动条样式;设为none为禁用

    • android:footDividersEnabled
      listview footer是否有分割线

    自定义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 getItemViewType(int position) {
              return data.get(position).getType() == title?0:1;
          }
      

    告诉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;
         }
    

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

    • 添加header,footer,OnItemClickListener中position
      listview添加上header,footer之后,实际的偏移量position应该加上header或者footer的数量

    • listview删除convertview缓存
      listview的优点之一,就是将view做了缓存,以convertview的形式取出;但有时有需求要删除convertview,刷一遍全新的界面。

       @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实例装载进来就行了。

    相关文章

      网友评论

          本文标题:ListView 使用总结

          本文链接:https://www.haomeiwen.com/subject/pkzxgttx.html