昨天要做一个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方法中直接设置进度条的进度即可实现。
分享到:
相关推荐
android ListView item下载 ListView 进度条下载 ListView多个下载 android:ListView的局部刷新 Android中自定义Adapter实现ListView动态刷新进度条 android listview局部刷新和模拟应用下载
android ListView item下载 ListView 进度条下载 ListView多个下载 android:ListView的局部刷新 Android中自定义Adapter实现ListView动态刷新进度条 android listview局部刷新和模拟应用下载
android listview 自定义样式实例 可以改造成自己所需风格
Android ListView每个Item上面的有TextView和Button,为ListView每个Item上面的按钮添加事件,并获取TextView文本信息。
c#自定义listview(可加入进度条) ,可添加图片,listview等
Android ListView 自定义adapter好友列表
实现ListView自定义Item,重写代理类,实现类似网易云pc客户端地效果
android中listview中的item内容不一样时,我们就可以通过自定义adapter来判断和控制不同的item显示内容
公司有个项目要用到类似手机QQ聊天记录列表ListView左右滑动后改变item的效果,网上没找到好的代码,偶然在安卓巴士的开源站http://d.apkbus.com/里面找到了SwipeToDismiss的源码...改成自己的显示另一个view的效果就行...
android中Listview的创建和几个视觉效果的设置
采用ListView控件加自定义适配器实现listview列表控件,代码简单,逻辑清楚,可扩展性强,并且解决了OOM,亲测绝对可以使用
Android自定义adapter的listview代码
ListView下拉刷新 ListView下拉刷新ListView下拉刷新ListView下拉刷新
android 里listView 拖动子item 删除该项
Android Listview Item上下拖动位置
NULL 博文链接:https://z466459262.iteye.com/blog/1284375
主要介绍了WPF的ListView控件自定义布局的方法,结合实例形式分析了WPF中ListView控件的布局方法,需要的朋友可以参考下
1.自定义ListView交叉表显示仓库颜色尺码库存数量 2.固定表头,支持上下滚动 3.固定前一列,支持左右滚动 4.按仓库分组显示 5.动态表头,列头,分组头 6.在android模拟器与真机上均测试通过
android ListView Item点击展开子项效果
Android 自定义ListView实现底部分页刷新与顶部下拉刷新 一.ListView 底部分页加载 整个底部分页加载,主要分一下几步: 1.加载底部自定义View; 2.响应OnScrollListener监听事件,onScroll方法记录最后可见的View ...