ListView,adapter使用总结

时间:2022-09-05 12:03:24

学习android也有一段时间了,老是想要通过总结的形式形成文档保存起来,但是一直都没能实现起来,一是本人挺懒的,有严重的拖延症,而是确实没什么时间来弄,每天回到宿舍已经是九点多了,宿舍人多,洗个澡,洗一下衣服,已经是十一点多了,不想明天的状态又是顶着两个黑眼圈来学习。所以,唉,还是自己的问题!
写总结,我越来越觉的很有必要,俗话说好记性不如烂笔头,你记性再好都会忘光光的,所以记录总结是最好的方式了。
好的,今天要总计的是ListView,就是一个列表视图,不要小看这个组件,很多的主流的app都用到了ListView,所先,这个ListView要怎么用呢?
ListView可以看成是一个容器,他所要存放的就是数据,然而,数据又不能直接存放在里面,必须通过一个中间件——适配器(Adapter),所以我们的重点就是了解并用好这个适配器。
适配器有三种,分别是数组适配器(ArrayAdapter),简单适配器(SimpleAdapter),通用适配器(BaseAdapter)。
数组设配器:
这个是三者中最简单的,我们通过代码来学习:
public class ListViewByEntity extends ActionBarActivity {

private ListView lvObj;

private String citys[]=new String[]{
        "北京",
        "上海",
        "广州",
        "成都",
        "安徽"
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_view_by_entity);

    lvObj=(ListView)findViewById(R.id.listView);
  ArrayAdapter<String> dataAdpater=new ArrayAdapter<String>(
            this,
            R.layout.item01,
            R.id.city,citys);*/

    ArrayAdapter<String> dataAdpater=new ArrayAdapter<String>(
            this,
            android.R.layout.simple_list_item_1,citys);

    //将适配器组件对象加载到ListView组件中
    lvObj.setAdapter(dataAdpater);


}

}
如代码中所见,实例化一个ArrayAdapter对象,他的构造器有三个参数,是 context:指当前窗体对象(上下文),resource:每个item对应布局文件的索引值,textViewResourceId:每个item对应布局文件里面对应TextView组件的ID值,objects:数组数据,里面的item布局一般是用android自带的布局R.layout.item01,实例化添加数据后,设配器里面就有数据了,ListView类中有setAdapter的方法,然后把设配器添加就去就可以了。
简单设配器(SimpleAdapter):
SimpleAdapter跟ArrayAdapter差不多一样,只不过SimpleAdapter是用ArrayList来存放数据,而且数据也比较复杂起来,示例代码如下,
private ListView lvObj;

private ArrayList<HashMap<String,Object>> data=new ArrayList<>();

private int qqiconIds[]=new int[]{
        R.drawable.orange_pic,
        R.drawable.apple_pic,
        R.drawable.banana_pic,
        R.drawable.pineapple_pic
};
private String qqnames[]=new String[]{
        "橘子",
        "苹果",
        "香蕉",
        "菠萝"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_view_by_simple_adpater);

    for(int index=0;index<qqnames.length;index++)
    {
        HashMap<String,Object> rowData=new HashMap<>();

        rowData.put("qqicon",qqiconIds[index]);
        rowData.put("qqname",qqnames[index]);

        data.add(rowData);
    }
    SimpleAdapter simpleAdapterData=new SimpleAdapter(
            this,
            data,
            R.layout.item02,
            new String[]{"qqicon","qqname"},
            new int[]{R.id.qqiconId,R.id.qqnameId}
            );

    lvObj=(ListView)findViewById(R.id.lvId);

    lvObj.setAdapter(simpleAdapterData);     
}

}
同样我们也是要实例化一个SimpleAdapter对象,他的构造方法也有这么几个参数,我们来看一下,context:指当前窗体对象(上下文),data:适配器的数据源,resource:每个item对应布局文件的索引值,from:每个item数据对应Map类型的key值,to:每个item对应布局文件里面的组件ID值(注意值顺序必须跟from一致),添加后就可以setAdapter进去了。
通用设配器(BaseAdapter):
这个设配器与前两个不同,这是需要我们自己来重写的一个适配器,其实,SimpleAdapter就是在ArrayAdapter里重写了一些代码,一般情况下,我们想要显示的数据都是比较复杂的,多种多样的,比如文本,图像,按钮,单选,复选等等,所以BaseAdapter是我们比较多用的设配器,这里我们用了一个内部类,继承BaseAdapter,实现他的几个方法,其中最主要的就是getView方法:
public class ListViewByBaseAdpater extends ActionBarActivity {
//自定义适配器
class MyAdpater extends BaseAdapter
{

    ArrayList<QqinfoEntity> list=new ArrayList<>();

    MyAdpater(ArrayList<QqinfoEntity> list) {
        this.list = list;
    }

    //返回有多少个item
    @Override
    public int getCount() {
        return list.size();
    }

    //获取item的数据对象
    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    //获取item的对应索引值
    @Override
    public long getItemId(int position) {
        return position;
    }

    public void addRowData(QqinfoEntity entity)
    {
        list.add(entity);
        notifyDataSetChanged();
    }

    //获取每个item对应的布局对象
    //convertView:存储item布局对象的缓冲
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        //动态加载布局文件,将布局文件转化为View对象

        View view;
        SurfaceHolder surfaceHolder;

        if(convertView==null)
        {
            view= LayoutInflater.from(ListViewByBaseAdpater.this).inflate(R.layout.item02,null);
            //获取item02布局文件里面的组件对象

            surfaceHolder=new SurfaceHolder();

            surfaceHolder.qqIconIamgeViewObj=(ImageView)view.findViewById(R.id.qqiconId);
            surfaceHolder.qqnameTvObj=(TextView)view.findViewById(R.id.qqnameId);

            view.setTag(surfaceHolder);

        }else{
            view=convertView;
            surfaceHolder=(SurfaceHolder)view.getTag();
        }

        QqinfoEntity entity=(QqinfoEntity)list.get(position);

        //将数据赋值给到ImageView组件和TextView组件
        surfaceHolder.qqIconIamgeViewObj.setImageDrawable(getResources().getDrawable(entity.getQqiconId()));
        surfaceHolder.qqnameTvObj.setText(entity.getQqname());

        return view;
    }

    class SurfaceHolder
    {
        ImageView qqIconIamgeViewObj;
        TextView  qqnameTvObj;
    }
}


ArrayList<QqinfoEntity> data=new ArrayList<>();

private ListView lvObj;
private Button addBtnObj;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_view_by_base_adpater);

    initData();

    lvObj=(ListView)findViewById(R.id.lvId);
    addBtnObj=(Button)findViewById(R.id.btnaddId);


    final MyAdpater myAdpaterObj=new MyAdpater(data);

    lvObj.setAdapter(myAdpaterObj);

    addBtnObj.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            QqinfoEntity entity=new QqinfoEntity();

// R.drawable.banana_pic
entity.setQqiconId(R.drawable.banana_pic);
entity.setQqname(“香蕉”);
myAdpaterObj.addRowData(entity);
}
});

}


//初始化集合数据
public void initData()
{
    int qqiconIds[]=new int[]{
            R.drawable.orange_pic,
            R.drawable.apple_pic
    };

    String qqnames[]=new String[]{
            "橘子",
            "苹果"
    };

    for(int index=0;index<qqiconIds.length;index++)
    {
        QqinfoEntity entity=new QqinfoEntity();

        entity.setQqiconId(qqiconIds[index]);
        entity.setQqname(qqnames[index]);

        data.add(entity);
    }    }

}
可以看到,adapter的主要功能实现就是在getView方法中,这里有一个技巧,就是如何优化adapter的数据,而不用每一次都是去findviewbyid,消耗内存,数据小看不出来,数据量一大就回不流畅起来,所以最好还是做一些优化,做法就是判断convertView缓存是否存在,不存在采取findviewbyid,存在就直接赋予就可以了。其中SurfaceHolder的这个类其实就是为了方便数据的存储而设置的,你也可以直接赋值。然后在oncreate实现添加adapter就可以了。
这些都是在Activity中用的比较多,现在基本用Fragment的比较多,那么如何在Fragment实现ListView,用之前的方法也是可以实现的,只是比较麻烦而已,最简单的就是让Fragment继承一个ListFragment的父类,但是你的布局文件中的listview中的id一定要是android:id/list,这是android规定的,具体的内容我会在后面的Fragment讲到。