Android逐條加載ListView,實現動畫更新
在Android應用中,如果ListView或是GridView裏麵的數據比較多的時候,加載會比較費時間,特別是裏麵有圖片的時候,需要花費的時間就更長,這樣就會出現一個長時間的等待黑屏界麵,這樣有時會給用戶造成一種錯覺,就是這個程序已經“死”了,,,
對於這個問題可以的一個方法是,添加一個ProgressDialog,顯示正在處理的窗口,等待加載完之後再關閉這個窗口,
但是這樣等所有的數據加載完之後,就是特別突然的顯示, 這樣用戶體驗也不佳,
以前看Android優化大師的時候,打開進程管理的時候,它是前麵顯示正在加載的ProgressDialog,然後也可以看到後台的數據正在逐條加載,這樣給人的感覺就好很多,現在就是要做這個效果~~~~
主要實現的思路是這樣的,新建一個線程,然後在線程裏麵獲取已經安裝的程序,再逐條把這些程序(數據)添加到緩衝數組中,再發送一個消息,更新顯示ListView的內容,當線程中所有的數據已經加載完的時候,再把ProgressDialog關掉,總的完成效果如下:

程序源代碼
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: https://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的內容,所以後麵改了一下源碼變成這個樣子:
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: https://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();
}
};
}
最後更新:2017-04-02 15:14:44