更新LisView里面的进度条
今天看到论坛上有人问这个。估计是要搞一个类似下载软件的东西吧。
所以就有了本篇,原理:
处理线程先给handler发消息,消息中包括进度信息,handler在去更改List的Adapter里面的信息,并通知List更新UI。
原理很简单,就直接上码了:
package hol.test.listprogress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class TestListProgress extends Activity {
private Button testDo = null;
private ListView progressList = null;
private List<HashMap<String, Object>> list;
private MyAdapter myAdapet;
private MyHandler myHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myHandler = new MyHandler();
findView();
addListerner();
initList();
}
private void findView() {
testDo = (Button) findViewById(R.id.btn_test);
progressList = (ListView) findViewById(R.id.lst_progress);
}
private void addListerner() {
testDo.setOnClickListener(new ClickEvent());
}
private void initList() {
list = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> dataA = new HashMap<String, Object>();
HashMap<String, Object> dataB = new HashMap<String, Object>();
dataA.put("title", "dataA");
dataA.put("current", 0);
list.add(dataA);
dataB.put("title", "dataB");
dataB.put("current", 0);
list.add(dataB);
myAdapet = new MyAdapter(TestListProgress.this, list);
progressList.setAdapter(myAdapet);
}
// 模拟处理线程
class UpdateRunnable implements Runnable {
int id;
int currentPos = 0;
int delay;
MyHandler handler;
public UpdateRunnable(int id, int delay, MyHandler handler) {
this.id = id;
this.handler = handler;
this.delay = delay;
}
@Override
public void run() {
// TODO Auto-generated method stub
while (currentPos <= 100) {
Message msg = handler.obtainMessage();
msg.what = 1;
msg.arg1 = id;
msg.arg2 = currentPos;
currentPos = currentPos + 5;
msg.sendToTarget();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 消息Handler用来更新UI
class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case 1:
int id = msg.arg1;
int current = msg.arg2;
updateProgress(id, current);
break;
}
super.handleMessage(msg);
}
private void updateProgress(int id, int currentPos) {
HashMap<String, Object> dataTemp = list.get(id);
dataTemp.put("current", currentPos);
myAdapet.chargeProgress(id, dataTemp);
}
}
// 按钮事件
class ClickEvent implements View.OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case (R.id.btn_test):
new Thread(new UpdateRunnable(0, 400, myHandler)).start();
new Thread(new UpdateRunnable(1, 200, myHandler)).start();
System.out.println("OnClick");
break;
}
}
}
// List的显示
class MyAdapter extends BaseAdapter {
List<HashMap<String, Object>> list;
LayoutInflater infl = null;
public MyAdapter(Context context, List<HashMap<String, Object>> list) {
this.infl = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(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 = infl.inflate(R.layout.list_layout, null);
ProgressBar progressBar = (ProgressBar) convertView
.findViewById(R.id.progress);
TextView titleView = (TextView) convertView
.findViewById(R.id.title);
HashMap<String, Object> detail = list.get(position);
String t = (String) detail.get("title");
titleView.setText(t);
int progress = (Integer) detail.get("current");
progressBar.setProgress(progress);
return convertView;
}
// 改变进度,postion就是要改的那个进度
public void chargeProgress(int postion, HashMap<String, Object> detail) {
this.list.set(postion, detail);
// System.out.println("charged:" + detail.get("current"));
notifyDataSetChanged();
}
}
}
MyAdapet 里面的 chargeProgress是在用来更新List里面的值。
Message里面arg1就是List中的第几个进度条,arg2就是这个进度条里面的当前应该有的进度。what暂时没什么意义,只是为了标识这类消息是用来更新进度条的。本例也只有这一类消息。
这个是List的LayoutXML文件内容:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="In list" android:layout_marginRight="5dip" > </TextView> <ProgressBar android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" android:max="100" android:layout_weight="1.0" android:visibility="visible" /> </LinearLayout>
Acitvity的布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button android:id="@+id/btn_test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ListProgress"
/>
<ListView android:id="@+id/lst_progress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0"
>
</ListView>
</LinearLayout>
效果图如下:

作者:holmes Zhang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。
浙公网安备 33010602011771号