Android开发之ListView实现Item局部刷新

 更新时间:2015年10月22日 09:24:09   作者:残剑_  
对于ListView数据的刷新大家都知道,改变Adapter的数据源,然后调用Adapter的notifyDateSetChanged()方法即可。通过本篇文章给大家详细介绍Android开发之ListView实现Item局部刷新,感兴趣的朋友一起学习吧

对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView。在这种模式下,我们会在getView中,根据不同的数据源,让控件显示不同的内容。这种模式是最常见的刷新模式,当我们来回滑动ListView的时候,调用adapter的getView方法,然后listview对adapter返回的View进行绘制。这种模式下,View的显示内容或状态都记录在adapter里面的数据源中,listview的更新频率不频繁,它随着数据源的变化而更新。

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

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

 private void updateView(int itemIndex) {
 //得到第一个可显示控件的位置,
 int visiblePosition = mListView.getFirstVisiblePosition();
 //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新
 if (itemIndex - visiblePosition >= ) {
 //得到要更新的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 = ;
 for(AppContent appContent : mList) {
  if(appContent.getUrl().equals(appContent.getUrl())) {
  itemIndex = mList.indexOf(appContent);
  appContent.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实现多任务多线程下载》的例子中的,如果需要可以去下载。

以上内容是关于Android开发之ListView实现Item局部刷新的全部内容,希望对大家有用,更多有关listview局部刷新问题,请登录脚本之家官网查询,谢谢!

相关文章

  • 详解Android中PopupWindow在7.0后适配的解决

    详解Android中PopupWindow在7.0后适配的解决

    本篇文章主要介绍了详解Android中PopupWindow在7.0后适配的解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • android6.0权限动态申请框架permissiondispatcher的方法

    android6.0权限动态申请框架permissiondispatcher的方法

    下面小编就为大家分享一篇android6.0权限动态申请框架permissiondispatcher的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Android RollPagerView实现轮播图

    Android RollPagerView实现轮播图

    这篇文章主要介绍了Android RollPagerView实现轮播图的相关资料,这里提供实例来实现轮播图的简单实例,希望能帮助到大家,需要的朋友可以参考下
    2017-08-08
  • Android 实现左滑出现删除选项

    Android 实现左滑出现删除选项

    滑动删除的部分主要包含两个部分, 一个是内容区域(用于放置正常显示的view),另一个是操作区域(用于放置删除按钮)。下面通过本文给大家介绍Android 实现左滑出现删除选项,需要的朋友可以参考下
    2017-06-06
  • Android 加载GIF图最佳实践方案

    Android 加载GIF图最佳实践方案

    最近在项目中遇到需要在界面上显示一个本地的 GIF 图的功能,下面通过本文给大家分享Android 加载GIF图最佳实践方案,需要的朋友参考下吧
    2017-08-08
  • gradle中的properties文件详解

    gradle中的properties文件详解

    这篇文章主要介绍了gradle中的properties文件详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Android组件必学之TabHost使用方法详解

    Android组件必学之TabHost使用方法详解

    这篇文章主要为大家详细介绍了Android组件中的TabHost组件使用方法,如何利用TabHost定义Tab标签样式,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Android接入阿里云热修复介绍

    Android接入阿里云热修复介绍

    大家好,本篇文章主要讲的是Android接入阿里云热修复介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • Android中 动态改变对话框值的方法

    Android中 动态改变对话框值的方法

    Android Dev-Guide 推荐重写Activity.onCreateDialog()方法来创建Dialog,这样Dialog就归属于这个Activity了。
    2013-04-04
  • Android采取ContentObserver方式自动获取验证码

    Android采取ContentObserver方式自动获取验证码

    这篇文章主要为大家详细介绍了Android采取ContentObserver方式自动获取验证码,感兴趣的小伙伴们可以参考一下
    2016-08-08

最新评论