Android實(shí)現(xiàn)listview動(dòng)態(tài)加載數(shù)據(jù)分頁的兩種方法
在android開發(fā)中,經(jīng)常需要使用數(shù)據(jù)分頁,比如要實(shí)現(xiàn)一個(gè)新聞列表的顯示,或者博文列表的顯示,不可能第一次加載就展示出全部,這就需要使用分頁的方法來加載數(shù)據(jù),在android中Handler經(jīng)常用來在耗時(shí)的工作中,它接收子線程發(fā)送的數(shù)據(jù),并使用數(shù)據(jù)配合更新UI,AsyncTask是在一個(gè)線程中執(zhí)行耗時(shí)操作然后把結(jié)果傳給UI線程,不需要你親自去管理線程和句柄。
一、使用Handler+線程方法
1、基礎(chǔ)知識(shí)
Handler在android系統(tǒng)中,主要負(fù)責(zé)發(fā)送和接收消息,它的用途主要有以下兩種:
(1)按照計(jì)劃來處理一個(gè)消息(sendMessage(Message)方法)或者執(zhí)行某個(gè)runnable實(shí)例(post(Runnable)方法)
(2)把其他的線程對(duì)象放入消息隊(duì)列中,避免線程沖突。
消息的發(fā)送通過post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int),sendMessage(Message), sendMessageAtTime(Message, long)和 sendMessageDelayed(Message, long) 方法完成。對(duì)于postXXX方法通過Runnable對(duì)象給消息隊(duì)列,并在消息隊(duì)列到達(dá)后被調(diào)用。對(duì)于sendMessageXXX方法,則傳遞一個(gè)包含message對(duì)象,該對(duì)象可以被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;// 每次下載十條數(shù)據(jù)
private List<News> newsList;
List<Map<String, String>> data ;
/*
* 設(shè)置布局顯示屬性
*/
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);
// 得到一個(gè)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;
}
/*
* 獲取網(wǎng)絡(luò)數(shù)據(jù) 注:我是訪問本機(jī)的一個(gè)新聞服務(wù),使用asp.net技術(shù)來實(shí)現(xiàn)的
* 這個(gè)是項(xiàng)目是一個(gè)基于android的資訊播報(bào)軟件
*/
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、小結(jié)
ListView使用Handler+線程方式來動(dòng)態(tài)加載數(shù)據(jù)的步驟如下:
1.先初始化頁面(如:加載第一頁數(shù)據(jù))
2.在接收某個(gè)事件的消息之后(以上代碼是onScroll事件),啟動(dòng)線程(線程完成下載數(shù)據(jù),并發(fā)送消息給handler)
3.handler接收到消息后更新界面,顯示數(shù)據(jù)。
二、使用AsyncTask方法
1、基礎(chǔ)知識(shí)
AsyncTask也是android提供的一個(gè)為了不能阻塞主線程的一個(gè)類,AsyncTask定義了三種泛型類型Params、Progress和Result,Params啟動(dòng)任務(wù)執(zhí)行輸入?yún)?shù),比如http請(qǐng)求的url和參數(shù),Progress后臺(tái)執(zhí)行任務(wù)的百分比,后臺(tái)執(zhí)行最終返回的結(jié)果。
AsyncTask的執(zhí)行分為四個(gè)步驟,每一步都對(duì)應(yīng)都對(duì)應(yīng)一個(gè)回調(diào)方法,開發(fā)者需要實(shí)現(xiàn)一個(gè)或者幾個(gè)方法,在任務(wù)的執(zhí)行過程中,這些方法會(huì)自動(dòng)調(diào)用。
onPreExecute(),在執(zhí)行后臺(tái)耗時(shí)操作前被調(diào)用,可以在執(zhí)行此方法中做一些ui操作,比如顯示一個(gè)進(jìn)度條等
doInBackground(Params...),這個(gè)方法在執(zhí)行onPreExecute()后執(zhí)行,這個(gè)方法完成耗時(shí)工作,比如下載等。
onProgressUpdate(Progress...),UI線程通過此方法獲取任務(wù)的完成的情況,比如完成的任務(wù)的百分比。
onPostExecute(Result),這個(gè)方法在耗時(shí)工作完成后被調(diào)用。UI線程調(diào)用此方法獲取結(jié)果。
注意:在使用AsyncTask類,有幾條準(zhǔn)則需要遵守
(1)、Task的實(shí)例必須在UI線程中創(chuàng)建
(2)、execute方法必須在UI線程中調(diào)用
(3)、不要手動(dòng)調(diào)用以上四個(gè)方法
(4)、這個(gè)任務(wù)只執(zhí)行一次(如果執(zhí)行第二次將會(huì)拋出異常)
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,了解詳細(xì)代碼
3、小結(jié)
ListView使用AsyncTask方法動(dòng)態(tài)加載數(shù)據(jù)的方法如下:
1.和handler一樣初始化頁面(如:加載第一頁)
2.在接收某個(gè)事件的消息之后(以上代碼是onScroll事件),創(chuàng)建一個(gè)新的異步任務(wù),并開始執(zhí)行
3.耗時(shí)工作完成后,開始更新UI
三、總結(jié)
使用Handler+線程和使用AsyncTask方法進(jìn)行ListView動(dòng)態(tài)加載的比較
Handler+線程方式:
在使用Handler方式時(shí),它涉及Handler、Thread、Message、Looper四個(gè)對(duì)象,在執(zhí)行的流程如下:主線程啟動(dòng)一個(gè)Thread,這個(gè)Thread執(zhí)行耗時(shí)操作,耗時(shí)操作完成后,生成一個(gè)Message,Looper讀取Message并傳遞給Hander,Handler接收Message并更新響應(yīng)的UI。因?yàn)長ooper在一個(gè)message處理完,才會(huì)讀下一條,如果發(fā)生多個(gè)Message就會(huì)形成一個(gè)消息隊(duì)列,所以它對(duì)多個(gè)后臺(tái)操作比較清晰,明朗。但對(duì)于單個(gè)message來講顯得代碼比較多,過于復(fù)雜。
AsyncTask方式:
AsyncTask繼承自O(shè)bject,是android提供的輕量級(jí)的異步類。并提供了一個(gè)方法來獲取任務(wù)的執(zhí)行進(jìn)度(可以根據(jù)它來更新UI),最后會(huì)把結(jié)果返回在主線程。這個(gè)方式的比較簡單,而且可以清楚的看到耗時(shí)任務(wù)執(zhí)行的進(jìn)度。但是對(duì)于多個(gè)異步操作同時(shí)進(jìn)行,并更新UI變得比較復(fù)雜。
附件上截圖


參考文章:Android listview動(dòng)態(tài)加載列表項(xiàng)實(shí)現(xiàn)代碼
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android列表組件ListView使用詳解之動(dòng)態(tài)加載或修改列表數(shù)據(jù)
- Android開發(fā)中Listview動(dòng)態(tài)加載數(shù)據(jù)的方法示例
- Android 動(dòng)態(tài)添加view或item并獲取數(shù)據(jù)的實(shí)例
- Android 根據(jù)EditText搜索框ListView動(dòng)態(tài)顯示數(shù)據(jù)
- Android實(shí)現(xiàn)ListView數(shù)據(jù)動(dòng)態(tài)加載的方法
- android ListView內(nèi)數(shù)據(jù)的動(dòng)態(tài)添加與刪除實(shí)例代碼
- Android實(shí)現(xiàn)動(dòng)態(tài)添加數(shù)據(jù)與堆疊折線圖詳解流程
相關(guān)文章
Android Studio升級(jí)到4.1以后插件問題解決
這篇文章主要介紹了Android Studio升級(jí)到4.1以后插件問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
android實(shí)現(xiàn)記住用戶名和密碼以及自動(dòng)登錄
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)記住用戶名和密碼以及自動(dòng)登錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
Android view滑動(dòng)懸浮固定效果實(shí)現(xiàn)代碼示例
本篇文章主要介紹了Android view滑動(dòng)懸浮固定效果實(shí)現(xiàn)代碼示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
Android 使用<layer-list>實(shí)現(xiàn)微信聊天輸入框功能
<layer-list> 標(biāo)簽可以設(shè)置LayerDrawable,一種有層次的Drawable疊加效果,<layer-list> 可以包含多個(gè) <item>標(biāo)簽。這篇文章主要介紹了Android 使用<layer-list>實(shí)現(xiàn)微信聊天輸入框,需要的朋友可以參考下2017-05-05
Android優(yōu)化查詢加載大數(shù)量的本地相冊(cè)圖片
本文介紹了Android優(yōu)化查詢加載大數(shù)量的本地相冊(cè)圖片,可以方便的照片的查詢,,感興趣的小伙伴們可以參考一下。2016-10-10

