更新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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。