热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

在android开发中,经常需要使用数据分页,比如要实现一个新闻列表的显示,或者博文列表的显示,不可能第一次加载就展示出全部,这就需要使用分页的方法来加载数据,在android中Handle

     在android开发中,经常需要使用数据分页,比如要实现一个新闻列表的显示,或者博文列表的显示,不可能第一次加载就展示出全部,这就需要使用分页的方法来加载数据,在android中Handler经常用来在耗时的工作中,它接收子线程发送的数据,并使用数据配合更新UI,AsyncTask是在一个线程中执行耗时操作然后把结果传给UI线程,不需要你亲自去管理线程和句柄。

一、使用Handler+线程方法

1、基础知识

Handler在android系统中,主要负责发送和接收消息,它的用途主要有以下两种:

(1)按照计划来处理一个消息(sendMessage(Message)方法)或者执行某个runnable实例(post(Runnable)方法)

(2)把其他的线程对象放入消息队列中,避免线程冲突。

     消息的发送通过post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int),sendMessage(Message), sendMessageAtTime(Message, long)和 sendMessageDelayed(Message, long) 方法完成。对于postXXX方法通过Runnable对象给消息队列,并在消息队列到达后被调用。对于sendMessageXXX方法,则传递一个包含message对象,该对象可以被Handler类的handlerMessage(Message)方法处理。

2、主要代码

  1 public class HandlerDemo extends Activity implements OnScrollListener {
2
3 private ListView mListView;
4 LinearLayout loadingLayout;
5 private Thread mThread;
6 private ListViewAdapter adapter;
7
8 private int startIndex = 1;// 从第1条开始
9 private int size = 10;// 每次下载十条数据
10 private List newsList;
11 List> data ;
12
13 /*
14 * 设置布局显示属性
15 */
16 private LayoutParams mLayoutParams = new LayoutParams(
17 LinearLayout.LayoutParams.WRAP_CONTENT,
18 LinearLayout.LayoutParams.WRAP_CONTENT);
19
20 private LayoutParams ffLayoutParams = new LayoutParams(
21 LinearLayout.LayoutParams.FILL_PARENT,
22 LinearLayout.LayoutParams.FILL_PARENT);
23
24 private ProgressBar progressBar;
25
26 @Override
27 protected void onCreate(Bundle savedInstanceState) {
28 // TODO Auto-generated method stub
29 super.onCreate(savedInstanceState);
30 setContentView(R.layout.news_main);
31 data=new ArrayList>();
32 addView();
33 }
34
35 private void addView() {
36 if (startIndex == 1) {
37 newsList = new ArrayList();
38 newsList = getNewsList();
39 }
40 getdata(newsList);
41 LinearLayout layout = new LinearLayout(this);
42 layout.setOrientation(LinearLayout.HORIZONTAL);
43 progressBar = new ProgressBar(this);
44 layout.addView(progressBar, mLayoutParams);
45 TextView textView = new TextView(this);
46 textView.setText("加载中...");
47 textView.setGravity(Gravity.CENTER_VERTICAL);
48 layout.addView(textView, ffLayoutParams);
49 layout.setGravity(Gravity.CENTER);
50 loadingLayout = new LinearLayout(this);
51 loadingLayout.addView(layout, mLayoutParams);
52 loadingLayout.setGravity(Gravity.CENTER);
53
54 // 得到一个ListView用来显示条目
55 mListView = (ListView) findViewById(R.id.listView);
56 mListView.addFooterView(loadingLayout);
57 adapter = new ListViewAdapter();
58 mListView.setAdapter(adapter);
59 mListView.setOnScrollListener(this);
60 mListView.setTextFilterEnabled(true);
61 }
62
63 @Override
64 public void onScroll(AbsListView view, int firstVisibleItem,
65 int visibleItemCount, int totalItemCount) {
66 // TODO Auto-generated method stub
67 if (firstVisibleItem + visibleItemCount == totalItemCount) {
68 if (mThread == null || !mThread.isAlive()) {
69 mThread = new Thread() {
70
71 @Override
72 public void run() {
73 newsList = new ArrayList();
74 newsList = getNewsList();
75 getdata(newsList);
76 Message msg = new Message();
77 msg.what = 1;
78 handler.sendMessage(msg);
79 }
80 };
81 mThread.run();
82 }
83 }
84 }
85
86 Handler handler = new Handler() {
87
88 @Override
89 public void handleMessage(Message msg) {
90 // TODO Auto-generated method stub
91 if (msg.what == 1) {
92 startIndex = startIndex + size;
93 Log.v("startindex", startIndex + "");
94 mListView.removeFooterView(loadingLayout);
95 mThread.stop();
96 adapter.count += size;
97 adapter.notifyDataSetChanged();
98 return;
99 }
100 }
101 };
102
103 class ListViewAdapter extends BaseAdapter {
104 int count = 10;
105
106 @Override
107 public int getCount() {
108 // TODO Auto-generated method stub
109 return count;
110 }
111
112 @Override
113 public Object getItem(int position) {
114 // TODO Auto-generated method stub
115 return position;
116 }
117
118 @Override
119 public long getItemId(int position) {
120 // TODO Auto-generated method stub
121 return position;
122 }
123
124 @Override
125 public View getView(int position, View convertView, ViewGroup parent) {
126 // TODO Auto-generated method stub
127 cOnvertView= LayoutInflater.from(getApplicationContext()).inflate(
128 R.layout.news_item, null);
129 TextView textView = (TextView) convertView
130 .findViewById(R.id.textNewsTitle);
131 textView.setText((data.get(position)).get("title"));
132 return convertView;
133 }
134 }
135
136 @Override
137 public void onScrollStateChanged(AbsListView view, int scrollState) {
138 // TODO Auto-generated method stub
139
140 }
141
142 private List> getdata(List list) {
143
144 if (list == null)
145 return null;
146 for (News news : list) {
147 Map map = new HashMap();
148 map.put("title", news.getTitle());
149 data.add(map);
150 }
151 return data;
152 }
153
154 /*
155 * 获取网络数据 注:我是访问本机的一个新闻服务,使用asp.net技术来实现的
156 * 这个是项目是一个基于android的资讯播报软件
157 */
158 private List getNewsList() {
159 String path = "http://10.0.2.2/getNewsList.aspx";
160 String xmlStr = "1,3,7"
161 + startIndex
162 + "
2"
163 + size
164 + "
";
165 NewsConnector newsCOnnector= new NewsConnector();
166 List list = new ArrayList();
167 list = newsConnector.getNewsList(path, xmlStr);
168 return list;
169 }
170 }

3、小结

ListView使用Handler+线程方式来动态加载数据的步骤如下:

1.先初始化页面(如:加载第一页数据)

2.在接收某个事件的消息之后(以上代码是onScroll事件),启动线程(线程完成下载数据,并发送消息给handler)

3.handler接收到消息后更新界面,显示数据。

 

二、使用AsyncTask方法

1、基础知识

AsyncTask也是android提供的一个为了不能阻塞主线程的一个类,AsyncTask定义了三种泛型类型Params、Progress和Result,Params启动任务执行输入参数,比如http请求的url和参数,Progress后台执行任务的百分比,后台执行最终返回的结果。

AsyncTask的执行分为四个步骤,每一步都对应都对应一个回调方法,开发者需要实现一个或者几个方法,在任务的执行过程中,这些方法会自动调用。

onPreExecute(),在执行后台耗时操作前被调用,可以在执行此方法中做一些ui操作,比如显示一个进度条等
doInBackground(Params...),这个方法在执行onPreExecute()后执行,这个方法完成耗时工作,比如下载等。
onProgressUpdate(Progress...),UI线程通过此方法获取任务的完成的情况,比如完成的任务的百分比。
onPostExecute(Result),这个方法在耗时工作完成后被调用。UI线程调用此方法获取结果。

注意:在使用AsyncTask类,有几条准则需要遵守

(1)、Task的实例必须在UI线程中创建

(2)、execute方法必须在UI线程中调用

(3)、不要手动调用以上四个方法

(4)、这个任务只执行一次(如果执行第二次将会抛出异常)

2、主要代码

 

 1 @Override
2 public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
3 // TODO Auto-generated method stub
4 if(arg1+arg2==arg3)
5 {
6 if(!isloading)
7 {
8 new myAsyncTask().execute(null);
9 }
10 else
11 {
12 mListView.removeFooterView(loadingLayout);
13 }
14 }
15 }
16
17 @Override
18 public void onScrollStateChanged(AbsListView arg0, int arg1) {
19 // TODO Auto-generated method stub
20
21 }
22
23 private class myAsyncTask extends AsyncTask
24 {
25
26 @Override
27 protected Void doInBackground(Void... params) {
28 // TODO Auto-generated method stub
29
30 newsList = new ArrayList();
31 newsList = getNewsList();
32 getdata(newsList);
33 return null;
34
35 }
36
37 @Override
38 protected void onPostExecute(Void result) {
39 // TODO Auto-generated method stub
40 super.onPostExecute(result);
41 adapter.count+=size;
42 adapter.notifyDataSetChanged();
43 startIndex+=size;
44 isloading=false;
45 }
46
47 @Override
48 protected void onPreExecute() {
49 // TODO Auto-generated method stub
50 super.onPreExecute();
51 isloading=true;
52 }
53
54 }

注:以上仅是和使用Handler+线程方法不同的代码,建议下载源码,了解详细代码

3、小结

ListView使用AsyncTask方法动态加载数据的方法如下:

1.和handler一样初始化页面(如:加载第一页)

2.在接收某个事件的消息之后(以上代码是onScroll事件),创建一个新的异步任务,并开始执行

3.耗时工作完成后,开始更新UI

 

三、总结

使用Handler+线程和使用AsyncTask方法进行ListView动态加载的比较

   Handler+线程方式:

在使用Handler方式时,它涉及Handler、Thread、Message、Looper四个对象,在执行的流程如下:主线程启动一个Thread,这个Thread执行耗时操作,耗时操作完成后,生成一个Message,Looper读取Message并传递给Hander,Handler接收Message并更新响应的UI。因为Looper在一个message处理完,才会读下一条,如果发生多个Message就会形成一个消息队列,所以它对多个后台操作比较清晰,明朗。但对于单个message来讲显得代码比较多,过于复杂。

  AsyncTask方式:

AsyncTask继承自Object,是android提供的轻量级的异步类。并提供了一个方法来获取任务的执行进度(可以根据它来更新UI),最后会把结果返回在主线程。这个方式的比较简单,而且可以清楚的看到耗时任务执行的进度。但是对于多个异步操作同时进行,并更新UI变得比较复杂。

 
附件上截图

  

下载源码

推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
author-avatar
lubin
追逐那一点星光
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有