`
f303153041
  • 浏览: 45593 次
社区版块
存档分类
最新评论

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方法中直接设置进度条的进度即可实现。
分享到:
评论
1 楼 603957521 2015-11-17  
能否提供代码,楼主,603957521@qq.com

相关推荐

    android listview局部刷新和模拟应用下载

    总的来说,这个Demo涵盖了Android开发中的多个知识点,包括ListView的局部刷新、异步任务、进度条更新以及文件下载管理。通过实践这个Demo,开发者可以深入理解Android UI更新机制以及后台任务的处理方式。

    android listview 实例demo

    在Android开发中,ListView是一个非常重要的组件,常用于展示大量数据列表。本教程将通过一个实例Demo来深入探讨如何在Android应用中有效地使用ListView。首先,我们来看一下ListView的基本概念和工作原理。 ...

    安卓Android源码——ListView下拉刷新 Demo.zip

    总之,通过这个Demo,开发者可以学习到如何在Android应用中实现ListView的下拉刷新功能,以及如何与后台数据交互,提升应用的交互性和实时性。通过深入研究源码,还能了解到更多关于SwipeRefreshLayout的工作原理和...

    Android利用在ListView添加一个加载View的方式实现上拉刷新

    通常,这个视图包含一个进度条、一个提示文字(如“正在加载...”)以及一个可选的取消刷新按钮。 - 在代码中,使用LayoutInflater解析此布局文件,并将其添加到ListView的Footer。 2. **设置Adapter** - 自定义...

    android 列表实现上拉加载更多 下拉刷新 选择性的item侧滑出按钮

    而"选择性的item侧滑出按钮"则为用户提供了一种快速操作列表项的交互方式,常见于邮件应用、待办事项列表等场景。这个Demo整合了这三个功能,解决了开发者在实际项目中可能遇到的需求。 1. **上拉加载更多**: 上...

    ListView 下拉刷新,上拉加载,滑动删除

    综上所述,"ListView 下拉刷新,上拉加载,滑动删除"是Android开发中提高用户体验的重要特性。通过集成和自定义相应的组件,开发者可以轻松实现这些功能,为用户提供更流畅、更便捷的操作方式。在实际应用中,还需要...

    分别设置listview加载中、空数据、加载数据失败三种状态的显示

    在布局文件中,可以创建一个包含进度条或者自定义动画的视图,然后在需要加载数据时,将这个视图设置为ListView的内容。 2. **空数据状态**:当数据源为空时,我们可以展示一个提示信息,告诉用户目前没有数据。...

    itemwithdel

    这个“itemwithdel”的项目就是针对这种需求设计的一个示例,它展示了如何在ListView的每个item上添加一个删除按钮,并在点击删除后实时刷新数据。 首先,我们需要在ListView的Adapter中创建一个新的视图(View)来...

    安卓Andriod源码——在Listview显示多任务下载效果。可以中途停止类似360手机助手.zip

    - ListView是Android中用于显示大量数据的视图组件,通常与Adapter一起使用,Adapter负责填充数据到ListView的各个Item。 - ListView通过复用View(也称为ViewHolder模式)来提高性能,避免为每个Item创建新的View...

    Android 开发技巧

    4.6.6、ListView自定义背景颜色 83 4.6.7、List长按与短按消息映射 84 4.6.8、点击ListView改变背景色 87 4.6.9、自动滚动ListView 88 4.6.10、BaseExpandableListAdapter例 88 4.6.11、列表视图(List View) 96 ...

Global site tag (gtag.js) - Google Analytics