您的位置:首页 > 移动开发 > Android开发

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

2016-06-01 22:25 281 查看
最近做一个项目需要实现类似应用宝的在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);
};
};


这里用到了圆形的进度条,具体的实现圆心进度条的方法可以百度一下,这里就不说了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: