最近在学习Android ,listview会经常使用到.做了些测试.有问题请指正.大家一起讨论.
ListviewTest.java Activity类
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class ListviewTest extends Activity implements OnClickListener{
int jobcounter = 0 ;
private static final int ADDJOB = 1001;
private static final int PROCESSADD = 1002;
private static final int PROCESSDONE = 1003;
private static final int ITEMBUTTON_CLICKED = 1004;
private static final String TAG = "ListviewTest";
protected static final long REFRESH_INTERVAL = 100;
protected boolean mBusy = false ;
long lastupdatetime = 0 ;
Object lock = new Object() ;
ListView listview ;
Button buttonadd ;
AddjavaListAdapter adapter ;
LayoutInflater inflater ;
LinkedHashMap<Integer, ListInfo> listdatas ;
LinkedHashMap<Integer, ListInfo> addlist = new LinkedHashMap<Integer, ListviewTest.ListInfo>() ;
List<Integer> delidlist = new ArrayList<Integer>() ;
Handler mainhandler = new Handler(){
public void handleMessage(android.os.Message msg) {
long v = System.currentTimeMillis() - lastupdatetime ;
switch (msg.what) {
case ADDJOB:
//if (inView(msg.arg1) && !mBusy) {
// Log.i(TAG, " ADDJOB done!") ;
updateListView();
lastupdatetime += REFRESH_INTERVAL ;
//}
break;
case PROCESSADD:
if ( !mBusy && v>REFRESH_INTERVAL) {
updateListView();
lastupdatetime = System.currentTimeMillis() ;
}
break;
case ITEMBUTTON_CLICKED:{
if(!listdatas.get(msg.arg1).running ) {
synchronized (listdatas.get(msg.arg1).lock) {
listdatas.get(msg.arg1).lock.notifyAll() ;
}
}
listdatas.get(msg.arg1).running = !listdatas.get(msg.arg1).running ;
if ( !mBusy ) {
updateListView();
lastupdatetime += REFRESH_INTERVAL ;
}
break;
}
case PROCESSDONE:
// Log.i(TAG, " PROCESSDONE done!"+msg.arg1) ;
synchronized (lock) {
delidlist.add(msg.arg1) ;
}
updateListView();
lastupdatetime += REFRESH_INTERVAL ;
break;
default:
break;
}
};
};
void updateListView(){
synchronized (lock) {
for (Integer delid : delidlist) {
Log.i(TAG, " PROCESSDONE done!"+delid) ;
listdatas.remove(delid) ;
}
listdatas.putAll(addlist) ;
for (ListInfo info : addlist.values()) {
//启动工作线程
new WorkThread("workthread#"+jobcounter,info).start() ;
jobcounter++ ;
}
//清空 delidlist 和 addlist
delidlist.clear() ;
addlist.clear() ;
}
adapter.notifyDataSetChanged();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
listdatas = new LinkedHashMap<Integer, ListInfo>() ;
super.onCreate(savedInstanceState);
setContentView(R.layout.listviewtest);
listview = (ListView) findViewById(R.id.listView001) ;
adapter = new AddjavaListAdapter();
listview.setAdapter(adapter) ;
//设置 当listview 进行上下拖动操作时的状态
listview.setOnScrollListener( new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_IDLE:
mBusy = false;
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
mBusy = true;
break;
case OnScrollListener.SCROLL_STATE_FLING:
mBusy = true;
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
}) ;
buttonadd = (Button) findViewById(R.id.button_listaddjob);
buttonadd.setOnClickListener(this);
inflater = LayoutInflater.from(this);
}
// 存放单条 listview 的数据
class ListInfo{
@Override
public String toString() {
return "ListInfo [index=" + index + ", id=" + id + ", running="
+ running + ", title=" + title + ", process=" + process
+ "]";
}
int index ;
long id ;
boolean running = true ;
String title ;
int process ;
Object lock = new Object();
}
class ViewHodler{
TextView text ;
ProgressBar bar ;
Button button ;
ItemClickListener listener;
}
// listview的适配器
class AddjavaListAdapter extends BaseAdapter {
@Override
public int getCount() {
return listdatas.keySet().size();
}
@Override
public Object getItem(int position) {
//从 listdata里获取 对应的数据 ,因为有删除的缘故.在有任务完成后 position不等于listdata的key
Object[] d = listdatas.keySet().toArray() ;
int c = (Integer)d[position] ;
// Log.i(TAG, "~~~~~getItem~~position["+position+"] [c="+c+"]") ;
return listdatas.get(c) ;
}
@Override
public long getItemId(int position) {
return ((ListInfo)this.getItem(position)).id ;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
ViewHodler holder ;
// 获取单条item 的view对象
if (v==null) {
v = inflater.inflate(R.layout.listview_item, null) ;
holder = new ViewHodler() ;
holder.text = (TextView) v.findViewById(R.id.textView_item) ;
holder.bar = (ProgressBar) v.findViewById(R.id.progressBar_item);
holder.button = (Button) v.findViewById(R.id.button_item) ;
holder.listener = new ItemClickListener() ;
v.setTag(holder) ;
}else{
holder = (ViewHodler) v.getTag();
}
//将数据显示到每个对应的 view上.
final ListInfo data = (ListInfo)getItem(position) ;
holder.listener.setId(data.index) ;
holder.button.setOnClickListener(holder.listener) ;
holder.text.setText(data.title) ;
holder.bar.setProgress(data.process) ;
if (data.running) {
holder.button.setText(R.string.item_stop) ;
}else{
holder.button.setText(R.string.item_start) ;
}
return v;
}
}
class ItemClickListener implements OnClickListener{
private int id ;
public void setId(int id) {
this.id = id;
}
@Override
public void onClick(View v) {
Log.i(TAG,"button clicked! "+id +"|"+listdatas.get(id).running+"-->"+!listdatas.get(id).running);
sendMessageToHandler(ITEMBUTTON_CLICKED,id) ;
}
}
class WorkThread extends Thread{
ListInfo in ;
public WorkThread(String name ,ListInfo in){
super(name) ;
this.in = in ;
}
@Override
public void run() {
ListInfo sdata = listdatas.get(in.index) ;
while(sdata.process<100) {
//如果暂停 则等待
if(!listdatas.get(in.index).running ) {
synchronized (listdatas.get(in.index).lock) {
try {
listdatas.get(in.index).lock.wait() ;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//模拟耗时任务操作
try {
Thread.sleep((int)(3000*new Random().nextDouble()));
} catch (InterruptedException e) {
e.printStackTrace();
}
sdata.process += new Random().nextInt(15)+1 ;
sendMessageToHandler(PROCESSADD,in.index) ;
}
//发送任务结束消息
if (sdata.process>=100) {
sendMessageToHandler(PROCESSDONE,in.index) ;
// Log.i(TAG, this.getName()+"#done") ;
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_listaddjob:{
ListInfo info = new ListInfo() ;
info.title = "file" + jobcounter ;
info.process = 0 ;
info.id = jobcounter ;
info.index = jobcounter ;
synchronized (lock) {
addlist.put(jobcounter, info) ;
}
sendMessageToHandler(ADDJOB,jobcounter) ;
break;
}
default:
break;
}
}
void sendMessageToHandler(int what,int arg1){
Message message = mainhandler.obtainMessage() ;
message.what = what ;
message.arg1 = arg1 ;
message.sendToTarget() ;
}
}
布局文件 listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listview_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="TextView" />
<ProgressBar
android:id="@+id/progressBar_item"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="0.75" />
<Button
android:id="@+id/button_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:text="@string/start" />
</LinearLayout>
布局文件 listviewtext.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button_listaddjob"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add" />
<ListView
android:id="@+id/listView001"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
程序运行效果