Android实现listview动态加载数据分页的两种方法_Android

在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、主要代码

public class HandlerDemo extends Activity implements OnScrollListener {

 private ListView mListView;
 LinearLayout loadingLayout;
 private Thread mThread;
 private ListViewAdapter adapter;

 private int startIndex = 1;// 从第1条开始
 private int size = 10;// 每次下载十条数据
 private List<News> newsList;
 List<Map<String, String>> data ;

 /*
 * 设置布局显示属性
 */
 private LayoutParams mLayoutParams = new LayoutParams(
  LinearLayout.LayoutParams.WRAP_CONTENT,
  LinearLayout.LayoutParams.WRAP_CONTENT);

 private LayoutParams ffLayoutParams = new LayoutParams(
  LinearLayout.LayoutParams.FILL_PARENT,
  LinearLayout.LayoutParams.FILL_PARENT);

 private ProgressBar progressBar;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.news_main);
 data=new ArrayList<Map<String, String>>();
 addView();
 }

 private void addView() {
 if (startIndex == 1) {
  newsList = new ArrayList<News>();
  newsList = getNewsList();
 }
 getdata(newsList);
 LinearLayout layout = new LinearLayout(this);
 layout.setOrientation(LinearLayout.HORIZONTAL);
 progressBar = new ProgressBar(this);
 layout.addView(progressBar, mLayoutParams);
 TextView textView = new TextView(this);
 textView.setText("加载中...");
 textView.setGravity(Gravity.CENTER_VERTICAL);
 layout.addView(textView, ffLayoutParams);
 layout.setGravity(Gravity.CENTER);
 loadingLayout = new LinearLayout(this);
 loadingLayout.addView(layout, mLayoutParams);
 loadingLayout.setGravity(Gravity.CENTER);

 // 得到一个ListView用来显示条目
 mListView = (ListView) findViewById(R.id.listView);
 mListView.addFooterView(loadingLayout);
 adapter = new ListViewAdapter();
 mListView.setAdapter(adapter);
 mListView.setOnScrollListener(this);
 mListView.setTextFilterEnabled(true);
 }

 @Override
 public void onScroll(AbsListView view, int firstVisibleItem,
  int visibleItemCount, int totalItemCount) {
 // TODO Auto-generated method stub
 if (firstVisibleItem + visibleItemCount == totalItemCount) {
  if (mThread == null || !mThread.isAlive()) {
  mThread = new Thread() {

   @Override
   public void run() {
   newsList = new ArrayList<News>();
   newsList = getNewsList();
   getdata(newsList);
   Message msg = new Message();
   msg.what = 1;
   handler.sendMessage(msg);
   }
  };
  mThread.run();
  }
 }
 }

 Handler handler = new Handler() {

 @Override
 public void handleMessage(Message msg) {
  // TODO Auto-generated method stub
  if (msg.what == 1) {
  startIndex = startIndex + size;
  Log.v("startindex", startIndex + "");
  mListView.removeFooterView(loadingLayout);
  mThread.stop();
  adapter.count += size;
  adapter.notifyDataSetChanged();
  return;
  }
 }
 };

 class ListViewAdapter extends BaseAdapter {
 int count = 10;

 @Override
 public int getCount() {
  // TODO Auto-generated method stub
  return count;
 }

 @Override
 public Object getItem(int position) {
  // TODO Auto-generated method stub
  return position;
 }

 @Override
 public long getItemId(int position) {
  // TODO Auto-generated method stub
  return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  // TODO Auto-generated method stub
  convertView = LayoutInflater.from(getApplicationContext()).inflate(
   R.layout.news_item, null);
  TextView textView = (TextView) convertView
   .findViewById(R.id.textNewsTitle);
  textView.setText((data.get(position)).get("title"));
  return convertView;
 }
 }

 @Override
 public void onScrollStateChanged(AbsListView view, int scrollState) {
 // TODO Auto-generated method stub

 }

 private List<Map<String, String>> getdata(List<News> list) {

 if (list == null)
  return null;
 for (News news : list) {
  Map<String, String> map = new HashMap<String, String>();
  map.put("title", news.getTitle());
  data.add(map);
 }
 return data;
 }

 /*
 * 获取网络数据 注:我是访问本机的一个新闻服务,使用asp.net技术来实现的
 * 这个是项目是一个基于android的资讯播报软件
 */
 private List<News> getNewsList() {
 String path = "http://10.0.2.2/getNewsList.aspx";
 String xmlStr = "<?xml version='1.0' encoding='utf-8'?><source><categoryIds>1,3,7</categoryIds><startIndex>"
  + startIndex
  + "</startIndex><detail>2</detail><count>"
  + size
  + "</count></source>";
 NewsConnector newsConnector = new NewsConnector();
 List<News> list = new ArrayList<News>();
 list = newsConnector.getNewsList(path, xmlStr);
 return list;
 }
}

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、主要代码

@Override
 public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
 // TODO Auto-generated method stub
 if(arg1+arg2==arg3)
 {
  if(!isloading)
  {
  new myAsyncTask().execute(null);
  }
  else
  {
  mListView.removeFooterView(loadingLayout);
  }
 }
 }

 @Override
 public void onScrollStateChanged(AbsListView arg0, int arg1) {
 // TODO Auto-generated method stub

 }

 private class myAsyncTask extends AsyncTask<Void, Void, Void>
 {

 @Override
 protected Void doInBackground(Void... params) {
  // TODO Auto-generated method stub

  newsList = new ArrayList<News>();
  newsList = getNewsList();
  getdata(newsList);
  return null;

 }

 @Override
 protected void onPostExecute(Void result) {
  // TODO Auto-generated method stub
  super.onPostExecute(result);
  adapter.count+=size;
  adapter.notifyDataSetChanged();
  startIndex+=size;
  isloading=false;
 }

 @Override
 protected void onPreExecute() {
  // TODO Auto-generated method stub
  super.onPreExecute();
  isloading=true;
 }

 }

注:以上仅是和使用Handler+线程方法不同的代码,建议下载源码:http://xiazai.jb51.net/201606/yuanma/NewsList(jb51.net).rar,了解详细代码
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变得比较复杂。

附件上截图

参考文章:Android listview动态加载列表项实现代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, asynctask
Handler+线程
listview分页加载、listview分页加载数据、listview的分页加载、listview分页加载demo、安卓listview分页加载,以便于您获取更多的相关知识。

时间: 2024-11-08 18:11:01

Android实现listview动态加载数据分页的两种方法_Android的相关文章

动态加载JavaScript文件的两种方法_javascript技巧

这篇文章主要为大家详细介绍了动态加载JavaScript文件的两种方法,感兴趣的小伙伴们可以参考一下 第一种便是利用ajax方式,把script文件代码从背景加载到前台,而后对加载到的内容经过eval()实施代码.第二种是,动静创建一个script标签,配置其src属性,经过把script标签插入到页面head来加载js,相当于正在head中写了一个<script src="..."></script>,只可是这个script标签是用js动静创建的 比喻说是我们

动态加载script文件的两种方法_javascript技巧

动态加载script到页面大约有俩方法 第一种就是利用ajax方式,把script文件代码从后台加载到前台,然后对加载到的内容通过eval()执行代码.第二种是,动态创建一个script标签,设置其src属性,通过把script标签插入到页面head来加载js,相当于在head中写了一个<script src="..."></script>,只不过这个script标签是用js动态创建的 比如说是我们要动态地加载一个callbakc.js,我们就需要这样一个scr

Android开发中Listview动态加载数据的方法示例

本文实例讲述了Android开发中Listview动态加载数据的方法.分享给大家供大家参考,具体如下: 最近在研究网络数据加载的问题,比如我有几百,甚至上千条数据,这些数据如果一次性全部加载到arraylist,然后再加载到Listview中.我们必然会去单独开线程来做,这样造成的结果就是会出现等待时间很长,用户体验非常不好.我的想法是动态加载数据,第一次加载十条,然后往下面滑动的时候再追加十条,再往下面滑动的时候再去追加,这样大大减少了用户等待的时间,同时给处理数据留下了时间.网上看到了这样一

动态加载js文件的三种方法

<script language="网页特效"> function importfn(){  var head = document.getelementsbytagname("head")[0];  var script = document.createelement('script');  script.id = 'sid';  script.type = 'text/javascript';  script.src = '../js/alertt

android listview 动态加载数据的问题

android UI进阶之实现listview的分页加载  手动加载 http://www.cnblogs.com/noTice520/archive/2012/02/10/2345057.html 滑动加载 http://www.cnblogs.com/leizhenzi/archive/2011/10/13/2210485.html http://www.cnblogs.com/tanlon/archive/2011/03/20/1989323.html android UI进阶之实现lis

动态加载JS文件的三种方法_javascript技巧

直接看实例.例1 重新加载js文件 复制代码 代码如下: function loadJs(file) {            var head = $("head").remove("script[role='reload']");            $("<scri" + "pt>" + "</scr" + "ipt>").attr({ role: 're

Java加载资源文件的两种方法

处理配置文件对于Java程序员来说再常见不过了,不管是Servlet,Spring,抑或是Structs,都需要与配置文件打交道.Java将配置文件当作一种资源(resource)来处理,并且提供了两个类来读取这些资源,一个是Class类,另一个是ClassLoader类.     当我们自己的程序需要处理配置文件时(比如xml文件或properties文件),通常会遇到两个问题:   (1)我的配置文件应该放在哪里? (2)怎么我的配置文件找不到了?     在了解了Java加载资源文件的机制

Android listview动态加载列表项实现代码_Android

最近了一个动态加载listview类表项的列子,分享出来大家学习学习,说说这个例子的实现过程,首先限定每次加载的列表项数据为10条数据,当拖动listview滚动到最后一条数据的时候再加载10条,并在Listview下方显示加载提示. 下面是我的java源码: private void showContent() { listView = (ListView) findViewById(R.id.journals_list_one); loadData(); adapter = new MyLi

Android实现Listview异步加载网络图片并动态更新的方法_Android

本文实例讲述了Android实现Listview异步加载网络图片并动态更新的方法.分享给大家供大家参考,具体如下: 应用实例:解析后台返回的数据,把每条都显示在ListView中,包括活动图片.店名.活动详情.地址.电话和距离等. 在布局文件中ListView的定义: <ListView android:id="@id/maplistview" android:background="@drawable/bg" android:layout_width=&qu