Android模拟ListView点击下载和局部刷新

来源:互联网 发布:姜gary结婚知乎 编辑:程序博客网 时间:2024/06/16 04:01

最近做一个项目需要实现类似应用宝的在listView中点击每一个Item的下载按钮时更新item和下载进度的功能,于是琢磨了一下,并且在网上参考了一些资料,实现了这个功能。
下面看看这个功能实现方式,
一、做一个模拟的数据源

public class GameListLvItem{    /**     * 从网络或缓存获取图片用的字符串     */    private String gameIcon;    private Drawable gameIconDraw;    private String gameName;    private long gameSize;    private String gameWebsite;    private long gameDownSize;    private int gameDownNum;    //用来判断是否可以下载的,默认为可以下载    private int downState;    public GameListLvItem() {        // TODO Auto-generated constructor stub    }    public GameListLvItem(String icon,String name,long size,String website,long gameDownSize,int downState) {        // TODO Auto-generated constructor stub        if (icon!=null) this.gameIcon = icon;        this.gameName = name;        this.gameSize = size;        this.gameWebsite = website;        this.gameDownSize = gameDownSize;        setGameDownNum(gameDownSize);        this.downState = downState;    }    public GameListLvItem(String gameIcon,String name,long size,long gameDownSize,String website) {        // TODO Auto-generated constructor stub        if (gameIcon!=null) this.gameIcon = gameIcon;        this.gameName = name;        this.gameSize = size;        this.gameDownSize = gameDownSize;        setGameDownNum(gameDownSize);        this.gameWebsite = website;    }    public GameListLvItem(Drawable icon,String name,long size) {        // TODO Auto-generated constructor stub        if (icon!=null) this.gameIconDraw = icon;        this.gameName = name;        this.gameSize = size;    }    public String getGameIcon() {        return gameIcon;    }    public void setGameIcon(String icon) {        this.gameIcon = icon;    }    public Drawable getGameIconDraw() {        return gameIconDraw;    }    public void setGameIconDraw(Drawable gameIconDraw) {        this.gameIconDraw = gameIconDraw;    }    public String getGameName() {        return gameName;    }    public void setGameName(String name) {        this.gameName = name;    }    public long getGameSize() {        return gameSize;    }    public void setGameSize(long size) {        this.gameSize = size;    }    public String getGameWebsite() {        return gameWebsite;    }    public void setGameWebsite(String website) {        this.gameWebsite = website;    }    public int getDownState() {        return downState;    }    public void setDownState(int downState) {        this.downState = downState;    }    public int getGameDownNum() {        return gameDownNum;    }    public void setGameDownNum(long gameDownSize) {        this.gameDownSize = gameDownSize;        this.gameDownNum = (int)(gameDownSize*100.0f/gameSize);    }}

二、下载的方法、这里我建立一个DownloadManager类,单例的,在这里用线程池来进行下载任务,具体的代码如下:

/** * 下载器,是单例的,用线程池来进行分别下载 *  * @author Alex * */public class DownLoadManager {    private Handler handler;    // 用来管理所有下载任务    private ArrayList<DownloadTask> taskList = new ArrayList<DownloadTask>();    /**     * 线程池接口     */    private ExecutorService executorService;    /** 单例对象 */    private static DownLoadManager downLoadManager;    /** 下载任务线程的集合 */    public DownLoadManager(Handler handler) {        // TODO Auto-generated constructor stub        executorService = Executors.newFixedThreadPool(3);        this.handler = handler;    }    public static DownLoadManager getInstance(Handler handler) {        if (downLoadManager == null) {            synchronized (DownLoadManager.class) {                if (downLoadManager == null) {                    downLoadManager = new DownLoadManager(handler);                }            }        }        return downLoadManager;    }    public void startDownload(int posi) {        DownloadTask task = new DownloadTask(posi);        taskList.add(task);        executorService.submit(task);    }    private class DownloadTask implements Runnable {        private int posi;        public DownloadTask(int posi) {            // TODO Auto-generated constructor stub            this.posi = posi;        }        @Override        public void run() {            // TODO Auto-generated method stub            for (int i = 0; i <= 5000; i+=50) {                try {                    Thread.sleep(200);                    Message message = handler.obtainMessage();                    message.arg1 = i;                    message.arg2 = posi;                    message.sendToTarget();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }    }

这个下载器模拟了不断增加的下载进度,并用handler发送消息,通知主线程实时修改界面

三、适配器,默认的处理不说了,最重要的是局部刷新的方法,这里来进行下载的刷新方法,其中最重要的操作是

/**     * 刷新单个item     *      * @param contentView     * @param posi     */    private void updateItem(int posi) {        //这个方法listView.getRefreshableView();是下拉刷新框架中的方法,得到下拉刷新列表中的listView,        //如果是listView就可以直接用mListView.getFirstVisiblePosition()来获取        ListView mListView = listView.getRefreshableView();        int visiblePos = mListView.getFirstVisiblePosition();        int offset = (posi+1) - visiblePos;        int lenth = mListView.getChildCount();        // 只有在可见区域才更新,因为不在可见区域得不到Tag,会出现空指针,所以这是必须有的一个步骤        if((offset < 0)||(offset>=lenth)) return;        View convertView = mListView.getChildAt(offset);        ViewHolder viewHolder = (ViewHolder) convertView.getTag();    viewHolder.downLoadProgress.setProgress(getList().get(posi).getGameDownNum());    }

四、在handler中改变Item

Handler handler = new Handler() {        public void handleMessage(Message msg) {            int progress = msg.arg1;            int posi = msg.arg2;            getList().get(posi).setGameDownNum(progress);            updateItem(posi);        };    };

这里用到了圆形的进度条,具体的实现圆心进度条的方法可以百度一下,这里就不说了。

1 0