Android之listview实现加载数据的动画

本文介绍了一种在Android应用中动态加载ListView的方法,通过创建线程逐条加载数据并在加载过程中更新UI,同时展示进度对话框,提供更好的用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:http://blog.youkuaiyun.com/yao_guet/article/details/6459112

 Android逐条加载ListView,实现动画更新

在Android应用中,如果ListView或是GridView里面的数据比较多的时候,加载会比较费时间,特别是里面有图片的时候,需要花费的时间就更长,这样就会出现一个长时间的等待黑屏界面,这样有时会给用户造成一种错觉,就是这个程序已经“死”了,,,

对于这个问题可以的一个方法是,添加一个ProgressDialog,显示正在处理的窗口,等待加载完之后再关闭这个窗口,

但是这样等所有的数据加载完之后,就是特别突然的显示, 这样用户体验也不佳,

以前看Android优化大师的时候,打开进程管理的时候,它是前面显示正在加载的ProgressDialog,然后也可以看到后台的数据正在逐条加载,这样给人的感觉就好很多,现在就是要做这个效果~~~~

 

主要实现的思路是这样的,新建一个线程,然后在线程里面获取已经安装的程序,再逐条把这些程序(数据)添加到缓冲数组中,再发送一个消息,更新显示ListView的内容,当线程中所有的数据已经加载完的时候,再把ProgressDialog关掉,总的完成效果如下:

 

程序源代码

 

 

[java]  view plain copy
  1. package com.sf.test;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import android.app.Activity;  
  5. import android.app.ProgressDialog;  
  6. import android.content.Context;  
  7. import android.content.Intent;  
  8. import android.content.pm.PackageManager;  
  9. import android.content.pm.ResolveInfo;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.view.KeyEvent;  
  14. import android.widget.ArrayAdapter;  
  15. import android.widget.ListView;  
  16. /** 
  17.  * @author Yao.GUET 
  18.  * blog: http://blog.youkuaiyun.com/Yao_GUET 
  19.  * 实现动态加载一个ListView 
  20.  */  
  21. public class ProcessorBarTest extends Activity {  
  22.     public static final int MSG_UPDATE_LIST = 18;  
  23.       
  24.     private ListView mApps;  
  25.     private Context mContext;  
  26.     private List<String> mAppList;  
  27.     private ProgressDialog dialog;  
  28.       
  29.     @Override  
  30.     protected void onCreate(Bundle savedInstanceState) {  
  31.         // TODO Auto-generated method stub  
  32.         super.onCreate(savedInstanceState);  
  33.         setContentView(R.layout.processorbar_test);  
  34.           
  35.         // ListView 列表 mApps  
  36.         mApps = (ListView)findViewById(R.id.lvProcessbar);  
  37.         mContext = this;  
  38.         mAppList = new ArrayList<String>();  
  39.           
  40.         // 设置正在处理窗口  
  41.         dialog = new ProgressDialog(mContext);  
  42.         dialog.setIcon(R.drawable.icon);  
  43.         dialog.setTitle("ProgressDialog");  
  44.         dialog.setMessage("Please wait while loading application list...");  
  45.         dialog.setCancelable(false);  
  46.         dialog.show();  
  47.           
  48.         // 开始动态加载线程  
  49.         mThreadLoadApps.start();  
  50.     }  
  51.       
  52.     private Thread mThreadLoadApps = new Thread(){  
  53.         @Override  
  54.         public void run() {  
  55.             int i = 0;  
  56.             // TODO Auto-generated method stub  
  57.               
  58.             // 获取已经安装程序列表  
  59.             PackageManager pm = mContext.getPackageManager();  
  60.             Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
  61.             mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
  62.             List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);  
  63.               
  64.             // 逐项添加程序,并发送消息更新ListView列表。  
  65.             for (i=0; i<list.size(); i++) {  
  66.                 mAppList.add(list.get(i).loadLabel(pm).toString());  
  67.                 handler.sendEmptyMessage(MSG_UPDATE_LIST);  
  68.             }  
  69.             // 关闭正在处理窗口  
  70.             dialog.dismiss();  
  71.         }  
  72.           
  73.     };  
  74.       
  75.     private Handler handler = new Handler(){  
  76.         @Override  
  77.         public void handleMessage(Message msg) {  
  78.             // TODO Auto-generated method stub  
  79.             switch (msg.what) {  
  80.             case MSG_UPDATE_LIST:  
  81.                 // 更新应用程序列表  
  82.                 mApps.setAdapter(new ArrayAdapter(mContext,   
  83.                         android.R.layout.simple_list_item_1, mAppList));  
  84.                 break;  
  85.             }  
  86.             super.handleMessage(msg);  
  87.         }  
  88.     };  
  89. }  
 

 

后面发现有效率更高的方法,其实不用每次更新一项都需要构建一个Adapter的,,,

把Adapter和一个List<?>绑定在一起之后,可以直接改变List<?>的内容,然后再使用Adapter的数据集更新通知,即可改变ListView的内容,所以后面改了一下源码变成这个样子,,,

[java]  view plain copy
  1. package com.Yao_GUET.test;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import android.app.Activity;  
  5. import android.app.ProgressDialog;  
  6. import android.content.Context;  
  7. import android.content.Intent;  
  8. import android.content.pm.PackageManager;  
  9. import android.content.pm.ResolveInfo;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.view.View;  
  14. import android.widget.AdapterView;  
  15. import android.widget.ArrayAdapter;  
  16. import android.widget.ListView;  
  17. /** 
  18.  * @author Yao.GUET 
  19.  * blog: http://blog.youkuaiyun.com/Yao_GUET 
  20.  * 实现动态加载一个ListView 
  21.  */  
  22. public class ProcessorBarTest extends Activity {  
  23.     public static final int MSG_UPDATE_LIST = 18;  
  24.       
  25.     private ListView mApps;  
  26.     private Context mContext;  
  27.     private List<String> mAppList;  
  28.     private ProgressDialog dialog;  
  29.     private ArrayAdapter mAdapter;  
  30.     private boolean mIsLoaded = false;  
  31.       
  32.     @Override  
  33.     protected void onCreate(Bundle savedInstanceState) {  
  34.         // TODO Auto-generated method stub  
  35.         super.onCreate(savedInstanceState);  
  36.         setContentView(R.layout.processorbar_test);  
  37.           
  38.         // ListView 列表 mApps  
  39.         mApps = (ListView)findViewById(R.id.lvProcessbar);  
  40.         mContext = this;  
  41.         mAppList = new ArrayList<String>();  
  42.         mAdapter = new ArrayAdapter(mContext,   
  43.                 android.R.layout.simple_list_item_1, mAppList);  
  44.         mApps.setAdapter(mAdapter);  
  45.           
  46.         // 设置正在处理窗口  
  47.         dialog = new ProgressDialog(mContext);  
  48.         dialog.setIcon(R.drawable.icon);  
  49.         dialog.setTitle("ProgressDialog");  
  50.         dialog.setMessage("Please wait while loading application list...");  
  51.         dialog.setCancelable(false);  
  52.         dialog.show();  
  53.           
  54.         // 开始动态加载线程  
  55.         mThreadLoadApps.start();  
  56.           
  57.         mApps.setOnItemClickListener(new AdapterView.OnItemClickListener(){  
  58.             public void onItemClick(AdapterView<?> parent, View v, int position,  
  59.                     long id) {  
  60.                 // TODO Auto-generated method stub  
  61.                 mAppList.remove(position);  
  62.                 mAdapter.notifyDataSetChanged();  
  63.             }  
  64.               
  65.         });  
  66.           
  67.         // 获取已经安装程序列表  
  68.         PackageManager pm = mContext.getPackageManager();  
  69.         Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
  70.         mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
  71.         List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);  
  72.           
  73.         // 逐项添加程序,并发送消息更新ListView列表。  
  74.         for (int i=0; i<list.size(); i++) {  
  75.             mAppList.add(list.get(i).loadLabel(pm).toString());  
  76.             mAdapter.notifyDataSetChanged();  
  77.         }  
  78.         mIsLoaded = true;  
  79.     }  
  80.       
  81.     private Thread mThreadLoadApps = new Thread(){  
  82.         @Override  
  83.         public void run() {  
  84.             int i = 0;  
  85.             // TODO Auto-generated method stub  
  86.             while (!mIsLoaded) {  
  87.                 try {  
  88.                     sleep(100);  
  89.                 } catch (InterruptedException e) {  
  90.                     e.printStackTrace();  
  91.                 }  
  92.             }  
  93.             // 关闭正在处理窗口  
  94.             dialog.dismiss();  
  95.         }  
  96.           
  97.     };  
  98. }  
 

 

2011-12-06更新,根据hb24775179 朋友的提示,第二个确实是不能达到效果的,

因为获取程序列表的操作放到UI线程里面,所以结果是当获取完程序列表的时候,都会显示progress dialog,这样反而不能达到效果了,

所以把获取程序列表的部分提取出来入放到子线程中处理,代码如下

[java]  view plain copy
  1. package com.progress;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.app.ProgressDialog;  
  8. import android.content.Context;  
  9. import android.content.Intent;  
  10. import android.content.pm.PackageManager;  
  11. import android.content.pm.ResolveInfo;  
  12. import android.os.Bundle;  
  13. import android.os.Handler;  
  14. import android.os.Message;  
  15. import android.view.View;  
  16. import android.widget.AdapterView;  
  17. import android.widget.ArrayAdapter;  
  18. import android.widget.ListView;  
  19. /**  
  20.  * @author Yao.GUET  
  21.  * blog: http://blog.youkuaiyun.com/Yao_GUET  
  22.  * 实现动态加载一个ListView  
  23.  */    
  24. public class ListViewTestActivity extends Activity {    
  25.     public static final int MSG_DISMISS_PROGRESS_DIALOG = 17;  
  26.     public static final int MSG_UPDATE_LIST = 18;  
  27.         
  28.     private ListView mApps;    
  29.     private Context mContext;    
  30.     private List<String> mAppList;    
  31.     private ProgressDialog dialog;    
  32.     private ArrayAdapter mAdapter;    
  33.     private boolean mIsLoaded = false;    
  34.         
  35.     @Override    
  36.     protected void onCreate(Bundle savedInstanceState) {    
  37.         // TODO Auto-generated method stub     
  38.         super.onCreate(savedInstanceState);    
  39.         setContentView(R.layout.main);    
  40.             
  41.         // ListView 列表 mApps     
  42.         mApps = (ListView)findViewById(R.id.lvProcessbar);    
  43.         mContext = this;    
  44.         mAppList = new ArrayList<String>();    
  45.         mAdapter = new ArrayAdapter(mContext,     
  46.                 android.R.layout.simple_list_item_1, mAppList);    
  47.         mApps.setAdapter(mAdapter);    
  48.             
  49.         // 设置正在处理窗口     
  50.         dialog = new ProgressDialog(mContext);    
  51.         dialog.setIcon(R.drawable.icon);    
  52.         dialog.setTitle("ProgressDialog");    
  53.         dialog.setMessage("Please wait while loading application list...");    
  54.         dialog.setCancelable(false);    
  55.         dialog.show();    
  56.             
  57.         // 开始动态加载线程     
  58.         mThreadObtainApps.start();  
  59.             
  60.         mApps.setOnItemClickListener(new AdapterView.OnItemClickListener(){    
  61.             public void onItemClick(AdapterView<?> parent, View v, int position,    
  62.                     long id) {    
  63.                 // TODO Auto-generated method stub     
  64.                 mAppList.remove(position);    
  65.                 mAdapter.notifyDataSetChanged();    
  66.             }    
  67.                 
  68.         });    
  69.     }  
  70.       
  71.     private Handler mHandler = new Handler() {  
  72.   
  73.         @Override  
  74.         public void handleMessage(Message msg) {  
  75.             // TODO Auto-generated method stub  
  76.             switch (msg.what) {  
  77.             case MSG_UPDATE_LIST:  
  78.                 mAdapter.notifyDataSetChanged();   
  79.                 break;  
  80.             case MSG_DISMISS_PROGRESS_DIALOG:  
  81.                 // 关闭正在处理窗口     
  82.                 dialog.dismiss();  
  83.                 break;  
  84.             default:  
  85.                 break;  
  86.             }  
  87.             super.handleMessage(msg);  
  88.         }  
  89.           
  90.     };  
  91.       
  92.     private Thread mThreadObtainApps = new Thread() {  
  93.         @Override  
  94.         public void run() {  
  95.             // 获取已经安装程序列表     
  96.             PackageManager pm = mContext.getPackageManager();    
  97.             Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);    
  98.             mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);    
  99.             List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);    
  100.                 
  101.             // 逐项添加程序,并发送消息更新ListView列表。     
  102.             for (int i=0; i<list.size(); i++) {    
  103.                 mAppList.add(list.get(i).loadLabel(pm).toString());  
  104.                 list.get(i).loadIcon(pm);  
  105.                 mHandler.sendEmptyMessage(MSG_UPDATE_LIST);  
  106.             }    
  107.             mHandler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);  
  108.         }  
  109.     };  
  110. }    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值