Android模拟ListView点击下载和局部刷新
2016-06-01 22:25
281 查看
最近做一个项目需要实现类似应用宝的在listView中点击每一个Item的下载按钮时更新item和下载进度的功能,于是琢磨了一下,并且在网上参考了一些资料,实现了这个功能。
下面看看这个功能实现方式,
一、做一个模拟的数据源
二、下载的方法、这里我建立一个DownloadManager类,单例的,在这里用线程池来进行下载任务,具体的代码如下:
这个下载器模拟了不断增加的下载进度,并用handler发送消息,通知主线程实时修改界面
三、适配器,默认的处理不说了,最重要的是局部刷新的方法,这里来进行下载的刷新方法,其中最重要的操作是
四、在handler中改变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); }; };
这里用到了圆形的进度条,具体的实现圆心进度条的方法可以百度一下,这里就不说了。
相关文章推荐
- 【Android】传感器(线性加速度、陀螺仪、磁场)信号实时获取,实时监测指定wifi、蓝牙信号强度
- Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
- 关于Android Studio第三方登录(使用QQ登录)代码
- Android 嵌套滚动条
- Android平台发展史
- Android基于事件监听器处理机制
- Android连续点击两次Back键退出程序
- Android 显示gif动画
- android隐藏信号栏
- Android Service实现闹钟
- Android MVP模式简介
- 疑惑:自定义控件中 TypedArray对象进行为什么要进行recycle()
- Android_Notes
- Android中的各种传感器
- Caused by: android.os.TransactionTooLargeException总结
- Caused by: android.os.TransactionTooLargeException总结
- Caused by: android.os.TransactionTooLargeException总结
- Android中ListView的工作原理
- 最全面的 Android 编码规范指南