Android listview动态添加删除更新带ProgressBar的Item

网上找资料看到一段代码,还是很不错的,至少里面逻辑处理挺好的,

但是如果我要实现局部更新单个ItemView的话不想用notifyDataSetChanged()可以用本文最末尾的方法测试下。微笑

MainActivity.java  Activity类

package com.example.androidlistprogress;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
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 MainActivity 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, MainActivity.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.activity_main);
         
        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("正在运行 ") ;
            }else{
                holder.button.setText("开始") ;
            }
             
            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="start progress" />

</LinearLayout>


布局文件 activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button_listaddjob"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="add a progress" />
 
    <ListView
        android:id="@+id/listView001"
        android:layout_below="@id/button_listaddjob"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</RelativeLayout>


 程序运行效果



[java]  view plain copy
  1. public void updateView(int itemIndex) {  
  2.         //得到第一个可显示控件的位置,  
  3.         int visiblePosition = mListView.getFirstVisiblePosition();  
  4.         //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新  
  5.         if (itemIndex - visiblePosition >= 0) {  
  6.             //得到要更新的item的view  
  7.             View view = mListView.getChildAt(itemIndex - visiblePosition);  
  8.             //从view中取得holder  
  9.             ViewHolder holder = (ViewHolder) view.getTag();  
  10.             HashMap<String, Object> item = data.get(itemIndex);  
  11.               
  12.             holder.listItem = (RelativeLayout) view.findViewById(R.id.rl_item);  
  13.             holder.ibPlay = (ImageButton) view.findViewById(R.id.ib_play);  
  14.             holder.ibDelete = (ImageButton) view.findViewById(R.id.ib_delete);  
  15.             holder.tvName = (TextView) view.findViewById(R.id.tv_record_sound_name);  
  16.             holder.tvLastModifyTime = (TextView) view  
  17.                     .findViewById(R.id.tv_record_time);  
  18.             holder.tvCurrentPlayTime = (TextView) view  
  19.                     .findViewById(R.id.tv_current_play_time);  
  20.             holder.tvTotalTime = (TextView) view.findViewById(R.id.tv_total_time);  
  21.             holder.sb = (MySeekBar) view.findViewById(R.id.pb_play);  
  22.             holder.layout = (LinearLayout) view  
  23.                     .findViewById(R.id.play_progress_info);  
  24.               
  25.             updateData(itemIndex, holder, item);  
  26.         }         
  27.     }  



自定义一个adapter继承BaseAdapter,写一个如上的方法,要更新数据时,不要调用notifyDataSetChanged()方法,调用上面的方法,即可做到更新单个item

这个艹蛋的问题,纠结了我好久。总算搞定了。。。


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值