自定义ListView动态加载数据

我们都知道网络取数据是耗时操作,如果我们一次性请求所有数据,假如数据量不多那还可以接受,但是如果数据量特别多,那么带来的后果就是用户的愤怒(用户是很没有耐心的),所以这时候我们就需要动态的加载数据,分批加载我们所需的数据,提升用户体验,先上图。

         

一般如果一个Activity集成越多的功能,代码量也会随之增多,看起来让人烦,我们可以考虑自定义控件将一些操作集成进去。

自定义ListView

 1 package com.example.listviewdynamicloading;
 2
 3 import android.content.Context;
 4 import android.util.AttributeSet;
 5 import android.view.LayoutInflater;
 6 import android.view.View;
 7 import android.widget.AbsListView;
 8 import android.widget.AbsListView.OnScrollListener;
 9 import android.widget.ListView;
10
11 public class ZdyListView extends ListView implements OnScrollListener {
12     private int totalItemCount;// 总数量;
13     private int lastVisibleItem;// 最后一个可见的item;
14     private boolean isLoading;
15     private View footer;
16     private LayoutInflater inflater;
17     public RefleshDatas refleshDatas;
18
19     public ZdyListView(Context context) {
20         super(context);
21         initView(context);
22     }
23
24     public ZdyListView(Context context, AttributeSet attrs) {
25         super(context, attrs);
26         initView(context);
27     }
28
29     public ZdyListView(Context context, AttributeSet attrs, int defStyle) {
30         super(context, attrs, defStyle);
31         initView(context);
32     }
33
34     private void initView(Context context) {
35         footer=inflater.from(context).inflate(R.layout.layout_util_footer, null);
36         this.setOnScrollListener(this);
37         this.addFooterView(footer);
38         this.removeFooterView(footer);
39     }
40
41     @Override
42     public void onScroll(AbsListView view, int firstVisibleItem,
43             int visibleItemCount, int totalItemCount) {
44         this.lastVisibleItem = firstVisibleItem + visibleItemCount;
45         this.totalItemCount = totalItemCount;
46     }
47
48     @Override
49     public void onScrollStateChanged(AbsListView view, int scrollState) {
50         //listview item总数量等于最后一个可见的item并且ListView停下不动了
51         if (totalItemCount == lastVisibleItem&& scrollState == SCROLL_STATE_IDLE) {
52             if (!isLoading) {
53                 isLoading = true;
54                 this.addFooterView(footer);
55                 if (refleshDatas != null) {
56                     //回调执行向服务器端请求数据
57                     refleshDatas.onLoading();
58                 }
59             }
60         }
61     };
62     public void loadComplete() {
63         isLoading = false;
64         this.removeFooterView(footer);//加载完毕,移除footView;
65     }
66     public void setInterface(RefleshDatas refleshDatas) {
67         this.refleshDatas = refleshDatas;
68     }
69     public interface RefleshDatas{
70         public void onLoading();
71     }
72 }

MainActivity

  1 package com.example.listviewdynamicloading;
  2
  3 import java.util.ArrayList;
  4
  5 import com.example.listviewdynamicloading.ZdyListView.RefleshDatas;
  6
  7 import android.app.Activity;
  8 import android.os.Bundle;
  9 import android.os.Handler;
 10 import android.os.Message;
 11 import android.view.Menu;
 12 import android.view.MenuItem;
 13 import android.widget.ListView;
 14 import android.widget.Toast;
 15
 16 public class MainActivity extends Activity{
 17     //一次从服务器端请求十条数据
 18     private int current=1;
 19     private int number=9;
 20
 21
 22     private ZdyListView listView; //自定义ListView,将footview,滑动监听等集合在一起,免得Activity代码过多
 23     private ArrayList<String> listDatas;
 24     private ListViewAdapter adapter;
 25
 26
 27     private Handler handler=new Handler(){
 28         public void handleMessage(android.os.Message msg) {
 29             switch (msg.what) {
 30             case 0x123:
 31                 setlistView((ArrayList<String>)msg.obj,"firstLoading");//firstLoading标志位代表数据是初次加载的
 32                 break;
 33             case 0x234:
 34                 setlistView((ArrayList<String>)msg.obj,"addLoading");//addLoading标志位代表数据是初次加载之后请求服务器所得
 35                 break;
 36             case 0x345:
 37                 showMsg((String)msg.obj);
 38                 break;
 39             default:
 40                 break;
 41             }
 42         };
 43     };
 44
 45     @Override
 46     protected void onCreate(Bundle savedInstanceState) {
 47         super.onCreate(savedInstanceState);
 48         setContentView(R.layout.activity_main);
 49         listDatas=new ArrayList<String>();
 50         listView=(ZdyListView) this.findViewById(R.id.listview);
 51         listView.setInterface(new RefleshDatas() {
 52             @Override
 53             public void onLoading() {
 54                 getDataThread(current, current+number, "addLoading");
 55             }
 56         });
 57     }
 58
 59
 60
 61     @Override
 62     protected void onStart() {
 63         super.onStart();
 64         getDataThread(current,number,"firstLoading");
 65     }
 66
 67     //.........................模拟开启线程向服务器请求数据.....................................
 68     private void getDataThread(final int current, final int number,final String type) {
 69         final Message msg=new Message();
 70         new Thread(){
 71             public void run() {
 72                 ArrayList<String> datas=ListViewDatas.returnNum(current, current+number);
 73                 if(datas!=null&&datas.size()>0){
 74                     switch (type) {
 75                     case "firstLoading":
 76                         msg.what=0x123;
 77                         break;
 78                     case "addLoading":
 79                         msg.what=0x234;
 80                         break;
 81                     default:
 82                         break;
 83                     }
 84                     msg.obj=datas;
 85                 }else {
 86                     msg.what=0x345;
 87                     msg.obj=datas;
 88                 }
 89                 handler.sendMessage(msg);
 90             };
 91         }.start();
 92     }
 93
 94
 95
 96     private void setlistView(ArrayList<String> datas,String type) {
 97         listDatas.addAll(datas);
 98         if(type.equals("firstLoading")){//初次加载
 99             adapter=new ListViewAdapter(MainActivity.this, listDatas);
100             current=adapter.getCount()+1;
101             listView.setAdapter(adapter);
102             listView.loadComplete();
103         }else if(type.equals("addLoading")){//初次加载后请求的数据,执行notifyDataSetChanged();
104             adapter.notifyDataSetChanged();
105             current=adapter.getCount()+1;
106             listView.loadComplete();
107         }
108     }
109
110
111     protected void showMsg(String str) {
112         Toast.makeText(MainActivity.this, "已加载完毕", Toast.LENGTH_SHORT).show();
113         listView.loadComplete();
114     }
115
116
117
118 }

模拟服务器端数据

 1 package com.example.listviewdynamicloading;
 2
 3 import java.util.ArrayList;
 4
 5 public class ListViewDatas {
 6     //模拟服务器端数据库中的数据,假设现在只有3条数据
 7     public static int NUM=53;
 8     public static ArrayList<String> returnNum(int startNum,int endNum){
 9         ArrayList<String> list=new ArrayList<String>();
10         if(endNum<=NUM){//客户端请求的数据在数据库数据范围之内
11             for(int i=startNum;i<=endNum;i++){
12                 list.add(String.valueOf(i));
13             }
14             return list;
15         }else if(endNum>=NUM&&startNum<=NUM){//客户端请求的数据不全在数据库数据范围之内
16             for(int i=startNum;i<=NUM;i++){
17                 list.add(String.valueOf(i));
18             }
19             return list;
20         }else if(startNum>NUM){//客户端请求的数据超出数据库数据范围之内
21             return null;
22         }
23         return null;
24     }
25 }

ListView适配器

 1 package com.example.listviewdynamicloading;
 2
 3 import java.util.ArrayList;
 4
 5 import android.content.Context;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.BaseAdapter;
10 import android.widget.TextView;
11
12 public class ListViewAdapter extends BaseAdapter{
13     private Context context;
14     private ArrayList<String> datas;
15
16     public ListViewAdapter(Context context,ArrayList<String> datas){
17         this.context=context;
18         this.datas=datas;
19     }
20
21     @Override
22     public int getCount() {
23         return datas.size();
24     }
25
26     @Override
27     public Object getItem(int position) {
28         return null;
29     }
30
31     @Override
32     public long getItemId(int position) {
33         return position;
34     }
35
36     @Override
37     public View getView(int position, View convertView, ViewGroup parent) {
38         ViewHolder vh=null;
39         if(convertView==null){
40             vh=new ViewHolder();
41             convertView=LayoutInflater.from(context).inflate(R.layout.listview_item, null);
42             vh.tv=(TextView) convertView.findViewById(R.id.tv);
43             convertView.setTag(vh);
44         }else {
45             vh=(ViewHolder) convertView.getTag();
46         }
47         vh.tv.setText("这是第"+datas.get(position)+"条数据");
48         return convertView;
49     }
50
51
52
53     class ViewHolder{
54         TextView tv;
55     }
56
57
58 }
时间: 2024-12-24 03:44:44

自定义ListView动态加载数据的相关文章

ListView动态加载数据分页(使用Handler+线程和AsyncTask两种方法)

ListView动态加载数据分页(使用Handler+线程和AsyncTask两种方法)

Android中ListView动态加载数据

1. 引言: 为了提高ListView的效率和应用程序的性能,在Android应用程序中不应该一次性加载ListView所要显示的全部信息,而是采取分批加载策略,随着用户的滑动,动态的从后台加载所需的数据,并渲染到ListView组件中,这样可以极大的改善应用程序的性能和用户体验. 2. 交互: 进入ListView组件,首先预加载N条记录,当用户滑动到最后一条记录显示加载提示信息,并从后台加载N条数据,接着渲染UI界面. 3. 效果图: 4. 程序实现: package com.focus.l

分享个刚写好的 android 的 ListView 动态加载类,功能全而代码少。

(转载声明出处:http://www.cnblogs.com/linguanh/) 简介:      该ListView 实现动态加载数据,为了方便用户充分地自定义自己的数据源.点击事件,等核心操作,本类采用接口形式提供上述具体操作!      1,所有关键的操作使用接口,由用户自己定义,              包括:数据适配器的配置.动态加载函数的配置.item点击接口;      2,已经新建线程来执行动态函数.      //3,提供一个默认的动态执行函数; 用法: 你只需要在自己的

ListView分页加载数据

在android软件开发中,ListView是一种经常被用到的组件.当需要用到列表显示的时候,通常都会用到.而使用的过程中也可能出现一些问题.比如,一次性加载过多的Item对于手机有限的内存来说,是一种负担.于是就有了分页加载的技术,一般的说,分页的使用方式有两种,一是在滑动到底部的时候,自动加载下一部分的内容.另一种则是在底部添加一个类似按钮的控件,点击后加载内容.这里介绍的是第一种.同样的,代码来自github,网址是:https://github.com/nicolasjafelle/Pa

Android-搭建简单服务端+ListView异步加载数据

Android-搭建简单服务端+ListView异步加载数据 2014年5月6日 本篇博文带给大家的是教大家如何在MyEclipse中搭建一个服务端,并通过手机端与其通信,异步加载数据. 笔者使用的是MyEclipse,各位也可以直接用Eclipse创建Java Web项目,谷歌提供的ADT Bundle是不能创建Web项目,读者可以下载Eclipse For JaveEE Developer这个IDE. 下面来介绍如何在MyEclipse创建一个Web项目,并部署到Tomcat当中,关于Tom

[JS前端开发] js/jquery控制页面动态加载数据 滑动滚动条自动加载事件

页面滚动动态加载数据,页面下拉自动加载内容 相信很多人都见过瀑布流图片布局,那些图片是动态加载出来的,效果很好,对服务器的压力相对来说也小了很多 有手机的相信都见过这样的效果:进入qq空间,向下拉动空间,到底部时,会动态加载剩余的说说或者是日志 今天我们就来看看他们的实现思路和js控制动态加载的代码 下面的代码主要是控制滚动条下拉时的加载事件的 在下面代码说明出,写上你的操作即可,无论是加载图片还是加载记录数据  都可以 别忘了引用jquery类库 [JavaScript] 纯文本查看 复制代码

android左右滑动加载分页以及动态加载数据

android UI 往右滑动,滑动到最后一页就自动加载数据并显示 如图: Java代码 package cn.anycall.ju; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.content.ActivityNotFoundException; impo

ASP.NET MVC动态加载数据

ASP.NET MVC动态加载数据,一般的做法是使用$.each方法来循环产生tabel: 你可以在html时先写下非动态的部分: <table> <tr> <th style="width:10px;"><input id="SelectAll" type="checkbox" /></th> <th>ID</th> <th>Port_Start&l

滚屏加载--无刷新动态加载数据技术的应用

index.html <?php require_once('connect.php'); //连接数据库 $user = array('demo1','demo2','demo3','demo3','<de></de>mo4'); //模拟了几个用户 ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtm