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

最近做一个项目需要实现类似应用宝的在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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值