Android ListView 自定义ITEM 为 进度条 按钮,进度条实时刷新

昨天要做一个MP3 多任务下载的下载管理功能,要把每个下载任务放到一个ITEM中,下载所以就会有进度条,为了可以手动开始暂停等操作,又在进度条下面增加了一个按钮,默认下载任务全部从数据库中读取,点击一个按钮,就开始一个下载任务,进度条实时更新。

download.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" >
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:divider="#330066"
android:dividerHeight="1px" >
</ListView>

</LinearLayout>

download_item.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" >

<TextView
android:id="@+id/title_down"
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="TextView" />

<ProgressBar
android:id="@+id/pb_down"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="30dp"
/>

<Button
android:id="@+id/bt_down"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始下载" />

</LinearLayout>

看到很多实现的方法都是开一个线程,然后handle 发送消息,handle接受到消息后,调用adapter的 notifyDataSetChanged() 方法来刷新LISTVIEW 这里总觉得有些麻烦,操作性太差了,自己试了一天都没搞定。
要注意的是 为了实现LISTVIEW里面的按钮事件,所以必须从BASEADAPTER 派生一个类,重写GETVIEW方法,如下:
class LvButtonAdapter extends BaseAdapter{
private List<Map<String ,Object>> mAppList;
private LayoutInflater mInflater;
private Context mContext;
private String [ ] keyString;
private int [ ] valueViewID;
public LvButtonAdapter( Context c, List <Map<String,Object>> appList, int resource,
String[ ] from , int[ ] to) {
mAppList = appList;
mContext = c;
mInflater = ( LayoutInflater) mContext. getSystemService(Context.LAYOUT_INFLATER_SERVICE) ;
keyString = new String [ from . length ] ;
valueViewID = new int [ to. length ] ;
System.arraycopy ( from , 0, keyString, 0, from . length ) ;
System.arraycopy ( to, 0, valueViewID, 0, to. length ) ;
}
@Override
public int getCount ( ) {
return mAppList. size ( ) ;
}
@Override
public Object getItem ( int position ) {
return mAppList. get ( position ) ;
}
@Override
public long getItemId( int position ) {
return position ;
}
@Override
public View getView(final int pos , View convertView, ViewGroup parent ) {
buttonViewHolder holder;
if ( convertView!= null ) {
holder = (buttonViewHolder)convertView.getTag ( ) ;
}else{
convertView = mInflater. inflate (R.layout.download_item, null ) ;
holder = new buttonViewHolder( ) ;
holder.muiscName =(TextView) convertView. findViewById(valueViewID[0]);
holder.pb = (ProgressBar)convertView.findViewById(valueViewID[1]);
holder.button = (Button)convertView.findViewById(valueViewID[2]);
convertView.setTag(holder);
}
System.out.println("current_pos:"+pos);
pb_list.add(holder.pb);
bt_list.add(holder.button);
Map<String,Object> appInfo = mAppList.get(pos) ;
if ( appInfo != null ) {
String aname = (String)appInfo.get(keyString[0]) ;
holder.muiscName.setText(aname);
holder.button.setOnClickListener(new OnClickListener()
{

@Override
public void onClick(View v) {
// TODO Auto-generated method stub

System.out.println("current pb:"+pos);
ProgressBar pb = pb_list.get(pos);
Button bt = bt_list.get(pos);
if(bt.getText().toString().equals("开始下载")
||bt.getText().toString()=="开始下载"){
bt.setText("正在下载");
Object[] obj = queryItem(dbHelper,pos+1);
pb.setMax(Integer.parseInt(String.valueOf(obj[1])));
int size = Integer.parseInt(String.valueOf(obj[1]));
String path = String.valueOf(obj[0]);
String name = String.valueOf(obj[2]);
download(bt,pb,pos,path+".mp3",name);
}
});
}
return convertView;
}
}


注意在getView中测试 输出ITEM 位置,发现在加载LISTVIEW的时候所有ITEM所在的位置
是按顺序一次性显示出来的,这意味着GETVIEW方法里面的任何一个控件都不是你点击按钮所得到的那个ITEM,所以我用了
private List<ProgressBar> pb_list = new ArrayList<ProgressBar>();
private List<Button> bt_list = new ArrayList<Button>();
把 进度条和按钮按照LISTVIEW的顺序全部添加进来。

在点击按钮的时候判断一下 根据ITEM的位置查出所对应的进度条,后面按钮也一样。
下面说到重点了,SERVICE 有两种启动方式 START 和 BIND ,而BINDservice SERVICE 是能直接和ACTIVITY交互的,所以在按钮点击事件中直接调用SERVICE 的下载方法,把进度条作为参数传递到SERVICE中,在SERVICE中会为每个按钮事件开启一条线程来处理一个下载任务。
下面是downloadservice 中的部分代码
public void downloader(Button bt,ProgressBar pb,int index,String url,String savepath,String filename){
try{
URL ur = new URL(url);
System.out.println(ur);
HttpURLConnection conn = (HttpURLConnection) ur.openConnection();
conn.connect();
fileSize = conn.getContentLength();
Log.e("length",String.valueOf(fileSize));
File file = new File(savepath+"/"+filename+".mp3");
DownLoadThread thread = new DownLoadThread(bt,pb,index,fileSize,file,conn,filename);
thread.start();
}catch(Exception e){
e.printStackTrace();
}
}

class DownLoadThread extends Thread{
public DownLoadThread(){

}
private int fileSize;
private File file;
private HttpURLConnection conn;
private DownloadInfo info;
private ProgressBar pb;
private Button bt;
private int index;
private String filename;
public DownLoadThread(Button bt,ProgressBar pb,int index,int fileSize,File file,HttpURLConnection conn,String filename){
this.fileSize =fileSize;
this.file = file;
this.conn = conn;
this.index = index;
this.pb = pb;
this.bt = bt;
this.filename = filename;
}
int i = 0;

@Override
public void run() {
// TODO Auto-generated method stub
BufferedReader br =null;
BufferedWriter bw = null;
MyMap cache = MyMap.getInstance();
try {
InputStream ins = conn.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
br = new BufferedReader(new InputStreamReader(ins));
bw = new BufferedWriter(new OutputStreamWriter(fos));
byte[] buffer=new byte[64];
int j = 0;
while((j=ins.read(buffer))!=-1){
i+=j;
fos.write(buffer,0,j);
pb.setProgress(i);
if(i==fileSize){
Intent intent = new Intent("com.download.service");
intent.putExtra("index",index);
intent.putExtra("name",filename);
intent.putExtra("current_pos",i);
sendBroadcast(intent);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

在RUN方法中直接设置进度条的进度即可实现。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值