Android之listview实现加载数据的动画
2015-12-05 17:43
621 查看
原文:http://blog.csdn.net/yao_guet/article/details/6459112
Android逐条加载ListView,实现动画更新
在Android应用中,如果ListView或是GridView里面的数据比较多的时候,加载会比较费时间,特别是里面有图片的时候,需要花费的时间就更长,这样就会出现一个长时间的等待黑屏界面,这样有时会给用户造成一种错觉,就是这个程序已经“死”了,,,
对于这个问题可以的一个方法是,添加一个ProgressDialog,显示正在处理的窗口,等待加载完之后再关闭这个窗口,
但是这样等所有的数据加载完之后,就是特别突然的显示, 这样用户体验也不佳,
以前看Android优化大师的时候,打开进程管理的时候,它是前面显示正在加载的ProgressDialog,然后也可以看到后台的数据正在逐条加载,这样给人的感觉就好很多,现在就是要做这个效果~~~~
主要实现的思路是这样的,新建一个线程,然后在线程里面获取已经安装的程序,再逐条把这些程序(数据)添加到缓冲数组中,再发送一个消息,更新显示ListView的内容,当线程中所有的数据已经加载完的时候,再把ProgressDialog关掉,总的完成效果如下:
程序源代码
[java] view
plaincopy
package com.sf.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* @author Yao.GUET
* blog: http://blog.csdn.net/Yao_GUET
* 实现动态加载一个ListView
*/
public class ProcessorBarTest extends Activity {
public static final int MSG_UPDATE_LIST = 18;
private ListView mApps;
private Context mContext;
private List<String> mAppList;
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.processorbar_test);
// ListView 列表 mApps
mApps = (ListView)findViewById(R.id.lvProcessbar);
mContext = this;
mAppList = new ArrayList<String>();
// 设置正在处理窗口
dialog = new ProgressDialog(mContext);
dialog.setIcon(R.drawable.icon);
dialog.setTitle("ProgressDialog");
dialog.setMessage("Please wait while loading application list...");
dialog.setCancelable(false);
dialog.show();
// 开始动态加载线程
mThreadLoadApps.start();
}
private Thread mThreadLoadApps = new Thread(){
@Override
public void run() {
int i = 0;
// TODO Auto-generated method stub
// 获取已经安装程序列表
PackageManager pm = mContext.getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
// 逐项添加程序,并发送消息更新ListView列表。
for (i=0; i<list.size(); i++) {
mAppList.add(list.get(i).loadLabel(pm).toString());
handler.sendEmptyMessage(MSG_UPDATE_LIST);
}
// 关闭正在处理窗口
dialog.dismiss();
}
};
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case MSG_UPDATE_LIST:
// 更新应用程序列表
mApps.setAdapter(new ArrayAdapter(mContext,
android.R.layout.simple_list_item_1, mAppList));
break;
}
super.handleMessage(msg);
}
};
}
后面发现有效率更高的方法,其实不用每次更新一项都需要构建一个Adapter的,,,
把Adapter和一个List<?>绑定在一起之后,可以直接改变List<?>的内容,然后再使用Adapter的数据集更新通知,即可改变ListView的内容,所以后面改了一下源码变成这个样子,,,
[java] view
plaincopy
package com.Yao_GUET.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* @author Yao.GUET
* blog: http://blog.csdn.net/Yao_GUET
* 实现动态加载一个ListView
*/
public class ProcessorBarTest extends Activity {
public static final int MSG_UPDATE_LIST = 18;
private ListView mApps;
private Context mContext;
private List<String> mAppList;
private ProgressDialog dialog;
private ArrayAdapter mAdapter;
private boolean mIsLoaded = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.processorbar_test);
// ListView 列表 mApps
mApps = (ListView)findViewById(R.id.lvProcessbar);
mContext = this;
mAppList = new ArrayList<String>();
mAdapter = new ArrayAdapter(mContext,
android.R.layout.simple_list_item_1, mAppList);
mApps.setAdapter(mAdapter);
// 设置正在处理窗口
dialog = new ProgressDialog(mContext);
dialog.setIcon(R.drawable.icon);
dialog.setTitle("ProgressDialog");
dialog.setMessage("Please wait while loading application list...");
dialog.setCancelable(false);
dialog.show();
// 开始动态加载线程
mThreadLoadApps.start();
mApps.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
// TODO Auto-generated method stub
mAppList.remove(position);
mAdapter.notifyDataSetChanged();
}
});
// 获取已经安装程序列表
PackageManager pm = mContext.getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
// 逐项添加程序,并发送消息更新ListView列表。
for (int i=0; i<list.size(); i++) {
mAppList.add(list.get(i).loadLabel(pm).toString());
mAdapter.notifyDataSetChanged();
}
mIsLoaded = true;
}
private Thread mThreadLoadApps = new Thread(){
@Override
public void run() {
int i = 0;
// TODO Auto-generated method stub
while (!mIsLoaded) {
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 关闭正在处理窗口
dialog.dismiss();
}
};
}
2011-12-06更新,根据hb24775179 朋友的提示,第二个确实是不能达到效果的,
因为获取程序列表的操作放到UI线程里面,所以结果是当获取完程序列表的时候,都会显示progress dialog,这样反而不能达到效果了,
所以把获取程序列表的部分提取出来入放到子线程中处理,代码如下
[java] view
plaincopy
package com.progress;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* @author Yao.GUET
* blog: http://blog.csdn.net/Yao_GUET
* 实现动态加载一个ListView
*/
public class ListViewTestActivity extends Activity {
public static final int MSG_DISMISS_PROGRESS_DIALOG = 17;
public static final int MSG_UPDATE_LIST = 18;
private ListView mApps;
private Context mContext;
private List<String> mAppList;
private ProgressDialog dialog;
private ArrayAdapter mAdapter;
private boolean mIsLoaded = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ListView 列表 mApps
mApps = (ListView)findViewById(R.id.lvProcessbar);
mContext = this;
mAppList = new ArrayList<String>();
mAdapter = new ArrayAdapter(mContext,
android.R.layout.simple_list_item_1, mAppList);
mApps.setAdapter(mAdapter);
// 设置正在处理窗口
dialog = new ProgressDialog(mContext);
dialog.setIcon(R.drawable.icon);
dialog.setTitle("ProgressDialog");
dialog.setMessage("Please wait while loading application list...");
dialog.setCancelable(false);
dialog.show();
// 开始动态加载线程
mThreadObtainApps.start();
mApps.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
// TODO Auto-generated method stub
mAppList.remove(position);
mAdapter.notifyDataSetChanged();
}
});
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case MSG_UPDATE_LIST:
mAdapter.notifyDataSetChanged();
break;
case MSG_DISMISS_PROGRESS_DIALOG:
// 关闭正在处理窗口
dialog.dismiss();
break;
default:
break;
}
super.handleMessage(msg);
}
};
private Thread mThreadObtainApps = new Thread() {
@Override
public void run() {
// 获取已经安装程序列表
PackageManager pm = mContext.getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
// 逐项添加程序,并发送消息更新ListView列表。
for (int i=0; i<list.size(); i++) {
mAppList.add(list.get(i).loadLabel(pm).toString());
list.get(i).loadIcon(pm);
mHandler.sendEmptyMessage(MSG_UPDATE_LIST);
}
mHandler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);
}
};
}
Android逐条加载ListView,实现动画更新
在Android应用中,如果ListView或是GridView里面的数据比较多的时候,加载会比较费时间,特别是里面有图片的时候,需要花费的时间就更长,这样就会出现一个长时间的等待黑屏界面,这样有时会给用户造成一种错觉,就是这个程序已经“死”了,,,
对于这个问题可以的一个方法是,添加一个ProgressDialog,显示正在处理的窗口,等待加载完之后再关闭这个窗口,
但是这样等所有的数据加载完之后,就是特别突然的显示, 这样用户体验也不佳,
以前看Android优化大师的时候,打开进程管理的时候,它是前面显示正在加载的ProgressDialog,然后也可以看到后台的数据正在逐条加载,这样给人的感觉就好很多,现在就是要做这个效果~~~~
主要实现的思路是这样的,新建一个线程,然后在线程里面获取已经安装的程序,再逐条把这些程序(数据)添加到缓冲数组中,再发送一个消息,更新显示ListView的内容,当线程中所有的数据已经加载完的时候,再把ProgressDialog关掉,总的完成效果如下:
程序源代码
[java] view
plaincopy
package com.sf.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* @author Yao.GUET
* blog: http://blog.csdn.net/Yao_GUET
* 实现动态加载一个ListView
*/
public class ProcessorBarTest extends Activity {
public static final int MSG_UPDATE_LIST = 18;
private ListView mApps;
private Context mContext;
private List<String> mAppList;
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.processorbar_test);
// ListView 列表 mApps
mApps = (ListView)findViewById(R.id.lvProcessbar);
mContext = this;
mAppList = new ArrayList<String>();
// 设置正在处理窗口
dialog = new ProgressDialog(mContext);
dialog.setIcon(R.drawable.icon);
dialog.setTitle("ProgressDialog");
dialog.setMessage("Please wait while loading application list...");
dialog.setCancelable(false);
dialog.show();
// 开始动态加载线程
mThreadLoadApps.start();
}
private Thread mThreadLoadApps = new Thread(){
@Override
public void run() {
int i = 0;
// TODO Auto-generated method stub
// 获取已经安装程序列表
PackageManager pm = mContext.getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
// 逐项添加程序,并发送消息更新ListView列表。
for (i=0; i<list.size(); i++) {
mAppList.add(list.get(i).loadLabel(pm).toString());
handler.sendEmptyMessage(MSG_UPDATE_LIST);
}
// 关闭正在处理窗口
dialog.dismiss();
}
};
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case MSG_UPDATE_LIST:
// 更新应用程序列表
mApps.setAdapter(new ArrayAdapter(mContext,
android.R.layout.simple_list_item_1, mAppList));
break;
}
super.handleMessage(msg);
}
};
}
后面发现有效率更高的方法,其实不用每次更新一项都需要构建一个Adapter的,,,
把Adapter和一个List<?>绑定在一起之后,可以直接改变List<?>的内容,然后再使用Adapter的数据集更新通知,即可改变ListView的内容,所以后面改了一下源码变成这个样子,,,
[java] view
plaincopy
package com.Yao_GUET.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* @author Yao.GUET
* blog: http://blog.csdn.net/Yao_GUET
* 实现动态加载一个ListView
*/
public class ProcessorBarTest extends Activity {
public static final int MSG_UPDATE_LIST = 18;
private ListView mApps;
private Context mContext;
private List<String> mAppList;
private ProgressDialog dialog;
private ArrayAdapter mAdapter;
private boolean mIsLoaded = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.processorbar_test);
// ListView 列表 mApps
mApps = (ListView)findViewById(R.id.lvProcessbar);
mContext = this;
mAppList = new ArrayList<String>();
mAdapter = new ArrayAdapter(mContext,
android.R.layout.simple_list_item_1, mAppList);
mApps.setAdapter(mAdapter);
// 设置正在处理窗口
dialog = new ProgressDialog(mContext);
dialog.setIcon(R.drawable.icon);
dialog.setTitle("ProgressDialog");
dialog.setMessage("Please wait while loading application list...");
dialog.setCancelable(false);
dialog.show();
// 开始动态加载线程
mThreadLoadApps.start();
mApps.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
// TODO Auto-generated method stub
mAppList.remove(position);
mAdapter.notifyDataSetChanged();
}
});
// 获取已经安装程序列表
PackageManager pm = mContext.getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
// 逐项添加程序,并发送消息更新ListView列表。
for (int i=0; i<list.size(); i++) {
mAppList.add(list.get(i).loadLabel(pm).toString());
mAdapter.notifyDataSetChanged();
}
mIsLoaded = true;
}
private Thread mThreadLoadApps = new Thread(){
@Override
public void run() {
int i = 0;
// TODO Auto-generated method stub
while (!mIsLoaded) {
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 关闭正在处理窗口
dialog.dismiss();
}
};
}
2011-12-06更新,根据hb24775179 朋友的提示,第二个确实是不能达到效果的,
因为获取程序列表的操作放到UI线程里面,所以结果是当获取完程序列表的时候,都会显示progress dialog,这样反而不能达到效果了,
所以把获取程序列表的部分提取出来入放到子线程中处理,代码如下
[java] view
plaincopy
package com.progress;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* @author Yao.GUET
* blog: http://blog.csdn.net/Yao_GUET
* 实现动态加载一个ListView
*/
public class ListViewTestActivity extends Activity {
public static final int MSG_DISMISS_PROGRESS_DIALOG = 17;
public static final int MSG_UPDATE_LIST = 18;
private ListView mApps;
private Context mContext;
private List<String> mAppList;
private ProgressDialog dialog;
private ArrayAdapter mAdapter;
private boolean mIsLoaded = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ListView 列表 mApps
mApps = (ListView)findViewById(R.id.lvProcessbar);
mContext = this;
mAppList = new ArrayList<String>();
mAdapter = new ArrayAdapter(mContext,
android.R.layout.simple_list_item_1, mAppList);
mApps.setAdapter(mAdapter);
// 设置正在处理窗口
dialog = new ProgressDialog(mContext);
dialog.setIcon(R.drawable.icon);
dialog.setTitle("ProgressDialog");
dialog.setMessage("Please wait while loading application list...");
dialog.setCancelable(false);
dialog.show();
// 开始动态加载线程
mThreadObtainApps.start();
mApps.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
// TODO Auto-generated method stub
mAppList.remove(position);
mAdapter.notifyDataSetChanged();
}
});
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case MSG_UPDATE_LIST:
mAdapter.notifyDataSetChanged();
break;
case MSG_DISMISS_PROGRESS_DIALOG:
// 关闭正在处理窗口
dialog.dismiss();
break;
default:
break;
}
super.handleMessage(msg);
}
};
private Thread mThreadObtainApps = new Thread() {
@Override
public void run() {
// 获取已经安装程序列表
PackageManager pm = mContext.getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
// 逐项添加程序,并发送消息更新ListView列表。
for (int i=0; i<list.size(); i++) {
mAppList.add(list.get(i).loadLabel(pm).toString());
list.get(i).loadIcon(pm);
mHandler.sendEmptyMessage(MSG_UPDATE_LIST);
}
mHandler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);
}
};
}
相关文章推荐
- s5p4418-sdio接口的wifi模块驱动及往android层的延伸
- android 之常见事件响应的实现方式对比
- android ExpandableListView的功能解析
- android - App manifest(3)
- android中dip、dp、px、sp和屏幕密度
- Android Studio编译Fresco
- Android tinysndfile
- android之实现带图片和文本的Button
- Android图片的一些处理
- Activity生命周期分析
- (Android)五分钟让你轻松学会下拉刷新和上拉加载更多
- android学习之路(六)---- 图片加载库的优化、封装
- Android SDK 开发范例大全 ---3.14控制不同的文字字体
- Android 点击Button更新接口数据刷新页面状态
- Android 获取系统状态栏的高度
- android 引用资源时,?android和@android的区别
- android(26)(使用开源框架xutils实现多线程断点下载)
- 【已解决】Android Studio项目编译出错,可以运行
- Android6.0 源码编译 + AS阅读源码
- android中截图并保存本地