对于ListView数据的刷新大家都知道,改变Adapter的数据源,然后调用Adapter的notifyDateSetChanged()方法即可。

  但是博主在做公司项目的时候,有个下载模块,因为可能同时下载好几个数据,所以用的listview展示所有正在下载的内容。因为下载进度要实时更新,所以要不停的调用notifyDateSetChanged刷新数据。这样会不停的重新绘制整个listview的界面,性能开销非常大。而且如果每个item有图片的话,每个item的图片都需要重新加载,就算图片做了内存缓存,刷新一下图片也会闪一下,不停的刷新就会导致各个item的图片不停的闪,体验一点都不好。

  那么对于上面问题,有没有解决办法呢?当然是有的。我们可以针对某一个item进行局部更新,而不影响其它没有修改的item。那么具体如何实现的呢?我们看下面的代码。

     private void updateView(int itemIndex) {
//得到第一个可显示控件的位置,
int visiblePosition = mListView.getFirstVisiblePosition();
//只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新
if (itemIndex - visiblePosition >= 0) {
//得到要更新的item的view
View view = mListView.getChildAt(itemIndex - visiblePosition);
//调用adapter更新界面
mAdapter.updateView(view, itemIndex);
}
}

  这个函数主要是根据传入的itemIndex来获取第itemIndex的数据所显示的view。itemIndex就是要修改的数据再List集合中的位置,比如我这里下载进度有更新,发了一个广播这里接收到了,需要修改该下载内容的进度条,广播接收器可以这么写:

         @Override
public void onReceive(Context context, Intent intent) {
AppContent appContent = intent.getParcelableExtra("appContent");
if(appContent == null) return;
int itemIndex = 0;
for(AppContent appContent1 : mList) {
if(appContent.getUrl().equals(appContent1.getUrl())) {
itemIndex = mList.indexOf(appContent1);
appContent1.setDownloadPercent(appContent.getDownloadPercent());
break;
}
}
updateView(itemIndex);
}

  下面看Adapter的具体代码:

 public class AppContentAdapter extends BaseAdapter{

     private List<AppContent> mDates = null;
private Context mContext; public AppContentAdapter(Context context) {
this.mContext = context;
} @Override
public int getCount() {
return mDates.size();
} @Override
public Object getItem(int position) {
return mDates.get(position);
} @Override
public long getItemId(int position) {
return position;
} public void setDates(List<AppContent> mDates) {
this.mDates = mDates;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(
R.layout.listitem_download, null);
holder.statusIcon = (DownloadPercentView) convertView.findViewById(R.id.status_icon);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.downloadPercent = (TextView) convertView.findViewById(R.id.download_percent);
holder.progressBar = (ProgressBar) convertView.findViewById(R.id.progressbar);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
setData(holder, position);
return convertView;
} /**
* 设置viewHolder的数据
* @param holder
* @param itemIndex
*/
private void setData(ViewHolder holder, int itemIndex) {
AppContent appContent = mDates.get(itemIndex);
holder.name.setText(appContent.getName());
holder.progressBar.setProgress(appContent.getDownloadPercent());
setIconByStatus(holder.statusIcon, appContent.getStatus());
if(appContent.getStatus() == AppContent.Status.PENDING) {
holder.downloadPercent.setVisibility(View.INVISIBLE);
} else {
holder.downloadPercent.setVisibility(View.VISIBLE);
holder.statusIcon.setProgress(appContent.getDownloadPercent());
holder.downloadPercent.setText("下载进度:" + appContent.getDownloadPercent() + "%");
}
} /**
* 局部刷新
* @param view
* @param itemIndex
*/
public void updateView(View view, int itemIndex) {
if(view == null) {
return;
}
//从view中取得holder
ViewHolder holder = (ViewHolder) view.getTag();
holder.statusIcon = (DownloadPercentView) view.findViewById(R.id.status_icon);
holder.name = (TextView) view.findViewById(R.id.name);
holder.downloadPercent = (TextView) view.findViewById(R.id.download_percent);
holder.progressBar = (ProgressBar) view.findViewById(R.id.progressbar);
setData(holder, itemIndex);
} /**
* 根据状态设置图标
* @param downloadPercentView
* @param status
*/
private void setIconByStatus(DownloadPercentView downloadPercentView, AppContent.Status status) {
downloadPercentView.setVisibility(View.VISIBLE);
if(status == AppContent.Status.PENDING) {
downloadPercentView.setStatus(DownloadPercentView.STATUS_PEDDING);
}
if(status == AppContent.Status.DOWNLOADING) {
downloadPercentView.setStatus(DownloadPercentView.STATUS_DOWNLOADING);
}
if(status == AppContent.Status.WAITING) {
downloadPercentView.setStatus(DownloadPercentView.STATUS_WAITING);
}
if(status == AppContent.Status.PAUSED) {
downloadPercentView.setStatus(DownloadPercentView.STATUS_PAUSED);
}
if(status == AppContent.Status.FINISHED) {
downloadPercentView.setStatus(DownloadPercentView.STATUS_FINISHED);
}
} private class ViewHolder {
private DownloadPercentView statusIcon;
private TextView name;
private TextView downloadPercent;
private ProgressBar progressBar;
}
}

  其实这些代码就是我上篇博文《AsyncTask实现多任务多线程下载》的例子中的,如果需要可以去下载。

ListView实现Item局部刷新的更多相关文章

  1. android Listview,gridview局部刷新,部分刷新

    众所周知Listview和Gridview的刷新界面的方式是调用adapter.notifyDataSetChanged()进行界面刷新. 但是此方法有其弊端,他是将界面中的数据全部刷新一遍,不论数据 ...

  2. 转 android Listview,gridview局部刷新,部分刷新 (仿QQ动态评论局部刷新)

    转自:http://blog.csdn.net/jdsjlzx/article/details/45582719 众所周知Listview和Gridview的刷新界面的方式是调用adapter.not ...

  3. Android 结合实际项目学会ListView局部刷新和相关知识《一》

    转载本专栏博客,请注明出处:道龙的博客 最近在公司参与的项目中有一个界面需要做局部UI更新处理,把其化烦为简为Demoi形式写在这里.我们还是运行该Demo,知道ListView局部刷新的使用场景:( ...

  4. android:ListView的局部刷新

    1.简介 对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView ...

  5. Android listview局部刷新和模拟应用下载(zhu)

    在android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用notifyDataSetChanged()这个函数,但是它会更新listview中所有可 ...

  6. ListView的局部刷新

    有的列表可能notifyDataSetChanged()代价有点高,最好能局部刷新. 局部刷新的重点是,找到要更新的那项的View,然后再根据业务逻辑更新数据即可. private void upda ...

  7. 转:android listview局部刷新和模拟应用下载

    在 android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用 notifyDataSetChanged()这个函数,但是它会更新listview中所 ...

  8. ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多

    ListView实现Item上下拖动交换位置  并且实现下拉刷新  上拉加载更多 package com.example.ListViewDragItem; import android.app.Ac ...

  9. 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路

    针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...

随机推荐

  1. mORMot 数据库操作

    程序中要使用数据库,首先是引用SynCommons, SynDB单元,根据不同的数据库类型,简单举几个例子: 1 使用Access数据库,引用SynCommons, SynDB,SynOleDb三个单 ...

  2. asp.net MVC 源码分析

    先上一张图吧 asp.net请求机制的图  by传智播客邹华栋老师 然后是 邹老师添加MVC请求过程的图 其实MVC 是在.netframework上加了一个过滤器  HttpModule 在C:\W ...

  3. "2013":爱你不容易

    2013对我来说确实像年初时曾给自己定义的那样,真的是非常不平常的一年.依稀记得去年年终时,BOSS和我深聊了1多钟头,谈到职业规划.人生还有家庭的林林种种.春节在家时也仔细考虑过2013自己该如何规 ...

  4. PHP 输出缓冲控制(Output Control) 学习

    php 缓冲简介 其实我对php ob 系列印象还是很模糊,具体怎么玩的,还不是很了解,平时curd,确实对这些内容没有深入.作为phper 甚是惭愧.网上搜了一通,互相copy,代码运行不能出现作者 ...

  5. [python] 线程池

    特别感谢simomo 什么是线程池? 诸如web服务器.数据库服务器.文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务.构建服务器应用程序的一个过于简单的模型是:每当一 ...

  6. C# web winform 路径

    string path = "";                if (System.Environment.CurrentDirectory == AppDomain.Curr ...

  7. three.js 之旅一

    扯一段废话,当你遇到一个没人知道的问题时,你该怎么办?         问周围人,他们遇到这种情况怎么办.作为程序员,这种情况肯定时有发生,我们要学会寻找资源. Three.js的六个基本步骤 1.设 ...

  8. java-GUI图形用户界面

    图形用户界面GUI(Graphical User Interface),指的是在一个程序中用户可以看到的和与之交互的部分. JavaAPI中提供两套组件用于支持编写用户界面AWT  and  Swin ...

  9. Java递归输出指定路径下所有文件及文件夹

    package a.ab; import java.io.File; import java.io.IOException; public class AE { public static void ...

  10. 『TCP/IP详解——卷一:协议』读书笔记——06

    2013-08-20 14:41:01 2.8 最大传输单元MTU MTU,最大传输单元:以太网和802.3对数据帧的长度都有一个限制,其最大值分别是1500和1492字节.这个不同网络对应的传输上限 ...