首页 > 代码库 > ListView实现下拉刷新-1-实现ListView

ListView实现下拉刷新-1-实现ListView

即使你不是需要这个项目,但通过这个项目,你会知道android的一些基础知识,对初学者的话帮助会比较大!

ListView做下拉刷新的源码为例,代码是有慕课网的老师提供的,真心感谢慕课网!

源码下载   (注意源码中,有两个类He,MyAdapter是为了测试而创建的,没有实际作用)

不是打广告(注意在边看解释的时候最好是边看代码)

综述:(分多篇的原因是:一起讲完的话,不一定能接受,而不是故意为了积分)

 第一篇:实现LIstView;重点在MyAdapter的实现上和convertView回收的机制;

 第二篇:将顶部布局加载到ListView中,即顶部布局初始化;

 第三篇:将顶部布局动态的显示出来,涉及到的功能和机理比较多,如接口回调机制,还有状态的设置;

现在开始吧!

首先看在这个程序中所需要的类:

548578bb0001ec9202370098.jpg

解释一下这四个类的作用:

 ApkEntity:作为ListView中单个Item所需数据的所有对象而封装出来的一个类,里面包括了三个String的对象,分别用于name,des,info,同时实现了类中各个对象的get,set方法;

 MainActivity:作为显示的主页面,用来显示ListView;

 MyAdapter:自定义的适配器,继承自BaseAdapter,是用于连接数据源和ListView之间的工具;

 ReFlashListView:自定义的ListView,继承自ListView,用于显示各个Item和最终的顶部布局;

之后再看一下这个程序中所需要的布局:

 共有三个布局:

 activity:用以显示listView;

 Item_layout:用来布置ListView中每个Item的显示样式;

 Header_layout:用来设置顶部的布局;


先看在MainActivity类中有三个成员变量:

ArrayList<ApkEntity> apk_list;
MyAdapter adapter;
ReFlashListView listview;
其中:ArrayList<> apk_list:作为数据源,可以将它看成一个数组,它里面元素的数据类型为ApkEntity,ApkEntity类在ApkEntity.java文件中定义的;

 MyAdapter,ReFlashListView分别是自定义的适配器与ListView;

在MainActivity类中有三个方法:
private void setData()
private void showList(ArrayList<ApkEntity> apk_list)
private void setReflashData()

其中setData():将数据添加到数据源中;

 showList():负责ListView加载适配器,和适配器的

 setReflashData():负责向数据源中写入新的数据,在接口回调过程中使用到,这里暂不讨论;

private void setData() {
        apk_list = new ArrayList<ApkEntity>();
        for (int i = 0; i < 10; i++) {
            ApkEntity entity = new ApkEntity();
            entity.setName("默认数据");
            entity.setDes("这是一个神奇的应用");
            entity.setInfo("50w用户");
            apk_list.add(entity); //将数据加入到数据源中;
        }
    }
   
    private void showList(ArrayList<ApkEntity> apk_list) {
        if (adapter == null) { //说明是首次加载
            listview = (ReFlashListView) findViewById(R.id.listview);
            listview.setInterface(this);
            adapter = new MyAdapter(this, apk_list);
            listview.setAdapter(adapter);
        }
        else {
            adapter.onDateChange(apk_list);
        }
    }

在showList中adapter,如果是第一次调用的话,因为之前一直没有实例化adapter,所以adapter为null,而在if的内部 adapter = new MyAdapter(this, apk_list);即adapter被实例化了,所以之后的都是在else中执行;if表示的意思是ListView首次加载Adapter,else 表示的意思是,更新数据源之后,更新适配器;

在MainActivity中还实现了接口IReflashListener,重写了onReflash(),但这涉及到接口回调的机制,所以暂不讨论;

最后在onCreate()函数中,他首先调用了setData,即创建数据源,之后又调用了showList,即ListView首次加载适配器;

接下来,我们开始分析MyAdapter类了:

MyAdapter继承自BaseAdapter类,下面补充android中各种适配器的继承关系,我希望你注意的是这些适配器各自的类型:想了解更多的话可以可以到我的博客上去看:

常用但忽略的anroid知识3-Adapter


548578f60001e46305000486.jpg

MyAdapter类中有两个成员变量:

ArrayList<ApkEntity> apk_list;
LayoutInflater inflater;
其中:ArrayList<ApkEntity> 类型的为数据源,大家肯定都不陌生了;
   LayoutInflater类是干什么的呢?他主要是用来连接xml与类的;具体想看功能的话,可以到我的博客上去看:

常用但忽略的android知识1-Inflate

ViewHolder:

MyAdapter类中有定义一个ViewHolder的类

class ViewHolder {
        TextView name_tv;
        TextView des_tv;
        TextView info_tv;
    }

这个ViewHolder的类主要是用在getView的函数中,获得Item布局中的三个TextView;

MyAdapter类中定义了6个方法:

 public MyAdapter(Context context, ArrayList<ApkEntity> apk_list)
    onDateChange(ArrayList<ApkEntity> apk_list)
    public int getCount()
    public Object getItem(int position)
    public long getItemId(int position)
    public View getView(int position, View convertView, ViewGroup parent)

MyAdapter是构造方法,其中的两个参数分别是上下文对象,和ArrayList数据源;

onDateChange用于刷新新数据并显示;
getCount:获得数据的个数;
getItem:获得position的Item对象;
getItemId:获得position的Item对象的ID;   

getView:获得position位置的Item的View;

在这里重点讨论getView方法,其他方法都是将对应ArrayList的相关数据放回即可;

public View getView(int position, View convertView, ViewGroup parent) {
        ApkEntity entity = apk_list.get(position);
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.item_layout, null);
            holder.name_tv = (TextView) convertView
                    .findViewById(R.id.item3_apkname);
            holder.des_tv = (TextView) convertView
                    .findViewById(R.id.item3_apkdes);
            holder.info_tv = (TextView) convertView
                    .findViewById(R.id.item3_apkinfo);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.name_tv.setText(entity.getName());
        holder.des_tv.setText(entity.getDes());
        holder.info_tv.setText(entity.getInfo());
        return convertView;
    }

注意到这里将convertView分为null和else,原因是涉及到convertView回收的机制:就是在初始显示的时候,每次显示一个item 都调用一次getview方法但是每次调用的时候covertview为空(因为还没有旧的view),当显示完了之后。如果屏幕移动了之后,并 且导致有些Item(也可以说是view)跑到屏幕外面,此时如果还有新的item需要产生,则这些item显示时调用的getview方法中的 convertview参数就不是null,而是那些移出屏幕的view(旧view),我们所要做的就是将需要显示的item填充到这些回收的 view(旧view)中去,最后注意convertview为null的不仅仅是初始显示的那些item,还有一些是已经开始移入屏幕但是还没有 view被回收的那些item。如果想看具体的讨论话,可以到我的博客上去看:

BaseAdapter中重写getview的心得以及发现convertView回收的机制

还有setTag和getTag,主要是将数据添加到Vew对象中,或者从View对象中取出数据,详细的在上面所链接的文章中有,可以看看,这里就不赘述了。

那么,第一部分ListView的实现的具体分析就到这里,下一篇是第二部分将顶部布局加载到ListView中,并实现下拉刷新的功能;重点是ReFlashListView的实现上。

未完待续。。。


ListView实现下拉刷新-1-实现ListView