1.什么是数据适配器?

用来建立数据源和数据渲染控件之间的关系,将数据的来源和数据的显示之间进行解耦,降低耦合性

2.BaseAdapter接口

BaseAdapter是一个抽象类(abstract)【以下代码为android源码】

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {    private final DataSetObservable mDataSetObservable = new DataSetObservable();    private CharSequence[] mAutofillOptions;    public boolean hasStableIds() {        return false;    }        public void registerDataSetObserver(DataSetObserver observer) {        mDataSetObservable.registerObserver(observer);    }    public void unregisterDataSetObserver(DataSetObserver observer) {        mDataSetObservable.unregisterObserver(observer);    }        /**     * Notifies the attached observers that the underlying data has been changed     * and any View reflecting the data set should refresh itself.     */    public void notifyDataSetChanged() {        mDataSetObservable.notifyChanged();    }    /**     * Notifies the attached observers that the underlying data is no longer valid     * or available. Once invoked this adapter is no longer valid and should     * not report further data set changes.     */    public void notifyDataSetInvalidated() {        mDataSetObservable.notifyInvalidated();    }    public boolean areAllItemsEnabled() {        return true;    }    public boolean isEnabled(int position) {        return true;    }    public View getDropDownView(int position, View convertView, ViewGroup parent) {        return getView(position, convertView, parent);    }    public int getItemViewType(int position) {        return 0;    }    public int getViewTypeCount() {        return 1;    }        public boolean isEmpty() {        return getCount() == 0;    }    @Override    public CharSequence[] getAutofillOptions() {        return mAutofillOptions;    }    /**     * Sets the value returned by {@link #getAutofillOptions()}     */    public void setAutofillOptions(@Nullable CharSequence... options) {        mAutofillOptions = options;    }}

需要实现的抽象方法有四种

public int getCount() 适配器中数据集中数据的个数 listview显示的总数据public Object getItem(int position) 获取数据集中与指定索引对应的数据项public long getItemId(int position) 获取指定行对应的idpublic View getView(int position,View convertView,ViewGroup parent):获取每一个Item显示的内容

3.如何使用BaseAdapter和ListView进行联动?

3-1:准备含ListView的总布局文件

<?xml version="1.0" encoding="utf-8"?>        

3-2:准备ListView中呈现的item的布局()

<?xml version="1.0" encoding="utf-8"?>            

3-3:构建数据源:
 

package com.app.baseadaptertraining;//构建数据源public class ItemBean {    public int itemImageResId;    public String itemTitle;    public String itemContent;    //添加构造方法    public ItemBean(int itemImageResId, String itemTitle, String itemContent) {        this.itemImageResId = itemImageResId;        this.itemTitle = itemTitle;        this.itemContent = itemContent;    }}

3-4:实现数据适配器(可优化)

package com.app.baseadaptertraining;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import java.util.List;/** * BaseAdapter 抽象类 */public class MyAdapter extends BaseAdapter {    private List mList;    private LayoutInflater mInflater;    //进行数据的初始化    //将数据源和数据适配器之间进行关联    public MyAdapter(Context context, List list) {        mList = list;        mInflater = LayoutInflater.from(context);    }    //返回ListView中的数据量    @Override    public int getCount() {        return mList.size();    }    //取得所含有的数据项    @Override    public Object getItem(int position) {        return mList.get(position);    }    //返回数据项的索引    @Override    public long getItemId(int position) {        return position;    }    //返回每一项的内容    //没有缓存机制    @Override    public View getView(int position, View convertView, ViewGroup parent) {        //可以将xml文件装换称为view        //开始装载视图        /**         * 每一次都是创建新的view,没有实现缓存机制 实现资源的极大浪费         * 效率极其低下         * View view=mInflater.inflate(R.layout.item,null);         *         //找到视图中的三个控件         *          ImageView imageView=(ImageView) view.findViewById(R.id.iv_image);         *         TextView title=(TextView)view.findViewById(R.id.tv_title);         *         TextView content=(TextView)view.findViewById(R.id.tv_content);         *         ItemBean bean=mList.get(position);         *         //开始进行数据的填充         *         imageView.setImageResource(bean.itemImageResId);         *         title.setText(bean.itemTitle);         *         content.setText(bean.itemContent);         * */        //*******************************************************************        //第一种优化方案:避免重复去创建view对象 但是fingViewById依旧会浪费大量的时间//        if (convertView == null) {//            convertView = mInflater.inflate(R.layout.item, null);//        }//            ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image);//            TextView title = (TextView) convertView.findViewById(R.id.tv_title);//            TextView content = (TextView) convertView.findViewById(R.id.tv_content);//            ItemBean bean = mList.get(position);//            //开始进行数据的填充//            imageView.setImageResource(bean.itemImageResId);//            title.setText(bean.itemTitle);//            content.setText(bean.itemContent);//            return convertView;        //*********************************************************************        //第二种优化方案        //1.避免convertView以及findViewById的优化        //ViewHolder        ViewHolder viewHolder;        if (convertView == null) {            viewHolder = new ViewHolder();            convertView = mInflater.inflate(R.layout.item, null);            //载入数据 findViewById()            viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_image);            viewHolder.content = (TextView) convertView.findViewById(R.id.tv_content);            viewHolder.title = (TextView) convertView.findViewById(R.id.tv_title);            //ViewHolder和convertView进行关联            convertView.setTag(viewHolder);        } else {            //取出关联的ViewHolder对象            viewHolder = (ViewHolder) convertView.getTag();        }        ItemBean bean = mList.get(position);        //开始进行数据的填充        viewHolder.imageView.setImageResource(bean.itemImageResId);        viewHolder.title.setText(bean.itemTitle);        viewHolder.content.setText(bean.itemContent);        return convertView;    }    //避免重复进行findViewById()    //建立映射条件    class ViewHolder {        //对应布局中的三个控件        public ImageView imageView;        public TextView title;        public TextView content;    }}

3-5:构建数据适配器和数据渲染器之间的联系(setAdapter)

package com.app.baseadaptertraining;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ListView;import java.util.ArrayList;import java.util.List;/** * 1.准备含ListView的总布局文件 * 2.准备单独的item文件 * 3.构造数据源(bean/pojo) * 4.实现数据适配器 BaseAdapter * 5.建立Adapter和ListView之间的联系 */public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        createMyList();    }    private void createMyList() {        List itemBeanList = new ArrayList<>();        //封装数据(准备假的数据)        for (int i = 0; i < 20; i++) {            //进行数据的填充            itemBeanList.add(new ItemBean(R.mipmap.ic_launcher, "这是一个title" + i, "这是一个content" + i));        }        //建立Adapter和ListView的联系        ListView listView = (ListView) findViewById(R.id.lv_main);        listView.setAdapter(new MyAdapter(this, itemBeanList));    }}

4.谈谈优化(主要是在构建Adapter的getView方法)

下面给出三种方案来构建视图

方案1:无优化,每一次均创建新的view,没有实现相应的缓存机制,实现资源的极大浪费

 public View getView(int position, View convertView, ViewGroup parent) {        //可以将xml文件装换称为view        //开始装载视图        /**         * 每一次都是创建新的view,没有实现缓存机制 实现资源的极大浪费         * 效率极其低下         * View view=mInflater.inflate(R.layout.item,null);         *         //找到视图中的三个控件         *          ImageView imageView=(ImageView) view.findViewById(R.id.iv_image);         *         TextView title=(TextView)view.findViewById(R.id.tv_title);         *         TextView content=(TextView)view.findViewById(R.id.tv_content);         *         ItemBean bean=mList.get(position);         *         //开始进行数据的填充         *         imageView.setImageResource(bean.itemImageResId);         *         title.setText(bean.itemTitle);         *         content.setText(bean.itemContent);                   return view;         * */}

方案2:部分优化,借助自带的convertView进行优化

(判断convertView是否为空,从而杜绝每一次都要构建view的情况,但是重复findViewById()依旧会消耗极大的内存)

if (convertView == null) {            convertView = mInflater.inflate(R.layout.item, null);        }            ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image);            TextView title = (TextView) convertView.findViewById(R.id.tv_title);         ItemBean bean = mList.get(position);            //开始进行数据的填充            imageView.setImageResource(bean.itemImageResId);            title.setText(bean.itemTitle);            content.setText(bean.itemContent);            return convertView;

方案3:全局优化,使用ViewHolder和convertView达到一种比较好的优化效果(相当于建立了两个缓存机制)

如果存在了视图组件,使用现成的convertView,无需重新创建

如果存在了控件,使用ViewHolder. 进行调用,无需重新查找控件位置

 @Override    public View getView(int position, View convertView, ViewGroup parent) {             //1.避免convertView以及findViewById的优化        //ViewHolder        ViewHolder viewHolder;        if (convertView == null) {            viewHolder = new ViewHolder();            convertView = mInflater.inflate(R.layout.item, null);            //载入数据 findViewById()            viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_image);            viewHolder.content = (TextView) convertView.findViewById(R.id.tv_content);            viewHolder.title = (TextView) convertView.findViewById(R.id.tv_title);            //ViewHolder和convertView进行关联            convertView.setTag(viewHolder);        } else {            //取出关联的ViewHolder对象            viewHolder = (ViewHolder) convertView.getTag();        }        ItemBean bean = mList.get(position);        //开始进行数据的填充        viewHolder.imageView.setImageResource(bean.itemImageResId);        viewHolder.title.setText(bean.itemTitle);        viewHolder.content.setText(bean.itemContent);        return convertView;    } //避免重复进行findViewById()    //建立映射条件    class ViewHolder {        //对应布局中的三个控件        public ImageView imageView;        public TextView title;        public TextView content;    }

 

更多相关文章

  1. (Android学习之路)Android中listView结合自定义适配器,并实现item
  2. OpenDanmaku实现弹幕效果
  3. Android(安卓)Material Design控件之FloatingActionButton
  4. Android自定义UI实战(基础篇1)---组合控件封装
  5. Android-Module:ToggleButton常用XML属性
  6. Android(安卓)Parcel和Parcelable类
  7. Android实现Tab布局的4种方式(Fragment+TabPageIndicator+ViewPag
  8. RecyclerView 中 item 点击事件的优化
  9. 【Android】5.3 单选和复选

随机推荐

  1. android 禁止屏幕转向
  2. Android多线程下载远程图片
  3. android防被杀
  4. 如何删除已安装的Android软件
  5. MoSync:跨多平台android,j2me, Symbian ,
  6. android使用AlarmManager实现应用每天定
  7. Android(安卓): 如何得到Activities栈顶
  8. Android多进程app中Application回调onCre
  9. 【iOS-cocos2d-X 游戏开发之三】Mac下配
  10. Android(安卓)4.1果冻豆新特性详解