`

关于ListView的Adapter,解决ListView滚动后内容重复的问题

 
阅读更多
http://www.cnblogs.com/3dant/archive/2011/04/06/2007060.html


这些天用到了ListView,由于要用到ImageView,且图片源不是在资源里面的,也就没法用到ID了,也就不能用SimpleAdapter之类的了。只能自己改写一个Adapter,直接继承BaseAdapter。由于一开始只是在网上看了一下如何写getView这个方法,根本没有去进一步理解各个参数的含义(当然现在也没有全理解。。。),一样一来,运行没问题了,ListView里面数据也有了,结果来了个Bug,滚动的时候有些地方会重复前面出现过的图片(或者说是第一页出现去的图片)。

正常情况下的getView方法体

public View getView(int position, View convertView, ViewGroup parent){

}

  里面比较纠结的就是View convertView。

  converView就是ListView里面每条记录(Item)的样式布局。

  在ListView里面每显示一条记录就会记录就会调用一次getView。但是为了优化速度,它只会缓存当前屏幕所显示的记录的View。这个可以在getView里面加一个输出语句,看getView什么时候执行,执行过多少次。就明白了。



?
 private LayoutInflater mInflater;
 @Override
  public View getView(int position, View convertView, ViewGroup parent) {    
      // TODO Auto-generated method stub
      ViewHolder  myViews;
      if (convertView == null){
          System.out.println("为空:" + position);          
          myViews = new ViewHolder ();
          convertView = mInflater.inflate(R.layout.lst_item, null);
          myViews.mNameText = (TextView) convertView.findViewById(R.id.clst);
          myViews.mPhoto = (ImageView) convertView.findViewById(R.id.mphoto);
          convertView.setTag(myViews);
      }
      else {
          myViews = (ViewHolder ) convertView.getTag();
          System.out.println("不为空:" + position);
      }
      
      Info p = infoList.get(position);
      String dn = p.getDisplayName;
   If (!dn== null){         
    myViews.mNameText.setText(dn);
  }
  Bitmap bm = p.getPhoto();
  If(!p == null){          
    myViews.mPhoto.setImageBitmap(bm);
  }
   //myViews.mNameText.setText(dn);
      //Bitmap bm = p.getPhoto();
      //myViews.mPhoto.setImageBitmap(bm);               
      return convertView;
  }

  static class ViewHolder {
      private TextView mNameText;
      private ImageView mPhoto;
}


  回到问题上来:

  出现重复内容,基本上都是使用了ViewHolder这种方法的。

  当我们判断 convertView == null  的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)。再用convertView的setTag将viewHolder设置进去。

如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder。

  后面就是对ViewHolder里面那些控件来进行设置,比如显示文字,显示图片什么的了。

  如果再接下来的设置中,有某些条记录的某些控件没有被赋值,比如TextView因为要设置的内容为空,或者ImageView因为图片为空就没有赋值,而是直接跳过了。就类似下面这种。



?
1
2
3
4
5
6
7
8
String t = XXX.getName;
Bitmap p = XXX.getPhoto;
If (!t == null){
mViewHolder.nameText.setText(t);
}
If(!p == null){
mViewHolder.photoView.setImageBitmap(p);
}
  前面说过,ListView只会缓存第一屏里面的List Item的视图布局,之后滚动ListView后面的Item的布局就都是用前面所缓存的视图布局(也就是convertView不为null)。这样如果当后面的某一条记录里面的某些控件因上面的原因没有赋值,就会直接使用前面所缓存的视图里面的值了(里面有值的话)。

  这样的最终效果就是,滚动的时候,会出现前面已经出现过的内容。



  最简单的解决方法就是,在上面的代码中不去判断赋值内容是否为空,而是直接设定对应该控件的值,即使用事例代码中的注释部分。(去掉上面代码中的if段)

  真正的解决方法,则规避不对ViewHolder中的元素进行赋值这种情况。拿上面的代码来说:



If (!t == null){
    mViewHolder.nameText.setText(t);
}


  这个时候,在t == null 时,就没有对viewHolder进行赋值,所以在t == null时,界面上的元素就有可能是没有更新的,也就是重复上一个(这个位置视图)。所以可以加上一个else,并在里面对viewholder进行赋值。

  

If (!t == null){
    mViewHolder.nameText.setText(t);
}else{
    mViewHolder.nameText.setText("unknow");
}


  这样问题就很好的解决了。



作者:holmes Zhang
来自博客园:http://www.cnblogs.com/3dant/archive/2011/04/06/2007060.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。
分享到:
评论

相关推荐

    Android中ListView+Adapter

    首先,`ListView`是一个可滚动的视图,用于显示一组项目,每个项目都是一个单独的视图。它通过复用视图(ViewHolder模式)提高性能,减少内存消耗,特别是在显示大量数据时。要使用ListView,你需要在布局XML文件中...

    listview适配器 ListViewAdapter和ViewHolder代码.rar

    ListView的高效渲染主要依赖于适配器(Adapter)机制,而ListViewAdapter和ViewHolder是实现这一机制的关键部分。本压缩包“listview适配器 ListViewAdapter和ViewHolder代码.rar”提供了一个简单的使用示例,帮助...

    Android listview与adapter用法

    具体来说,Adapter负责将后端的数据模型转换为前端视图可以理解的形式,使得数据能够被正确地显示在ListView、GridView等可滚动视图中。 - 在Android中,Adapter通常实现了一个或多个特定接口,例如BaseAdapter、...

    安卓listview相关相关-解决ScrollView里面嵌套ListVIew引起的高度和滚动问题.zip

    然而,当在一个ScrollView内嵌套一个ListView时,常常会遇到一些问题,比如滚动冲突、布局高度计算错误等。这个问题是由于两个可滚动组件共存导致的,Android系统无法正确处理它们之间的交互。 首先,我们要理解...

    Android实现的ListView-ListViewAdapter(新闻列表事例)

    在这个“Android实现的ListView-ListViewAdapter(新闻列表事例)”中,我们将探讨如何利用ListView和ListViewAdapter来构建一个新闻列表,具体涵盖以下几个关键知识点: 1. **ListView**: ListView是Android SDK中的...

    解决ScrollView,ListView滚动条冲突

    本篇文章将详细讲解如何解决ScrollView与ListView滚动条冲突,并将这一解决方案扩展到其他具有滚动条的控件。 首先,我们来理解问题的本质。ScrollView是一个可以包含多个子视图的垂直滚动容器,而ListView则是一个...

    ListViewAdapter和ViewHolder代码,安卓listview适配器.rar

    本资源包含了一个关于ListViewAdapter和ViewHolder的代码示例,帮助开发者更好地理解和实现这个功能。 **ListViewAdapter详解** ListViewAdapter是Android SDK提供的一个抽象类,它是BaseAdapter的子类。开发者需要...

    解决scrollView和listview滚动冲突,实现listview滑动到顶端和底部之后还能拖拽一定的距离,松开后返回

    ScrollView是一个可以包含单个子视图的可滚动容器,而ListView则是通过Adapter来动态加载和展示数据的列表。默认情况下,当两者在同一层级时,触摸事件会被ScrollView捕获,导致ListView无法正常滚动。为了解决这个...

    Android之自定义Adapter的ListView

    接着,创建了一个名为`ListViewAdapter`的自定义Adapter,继承自`BaseAdapter`,并传入上下文和数据集作为构造函数参数。然后,通过`listView.setAdapter(listViewAdapter)`将Adapter绑定到ListView上。 在`getView...

    监听listview垂直滚动距离

    此外,对于"GoTopDemo"这个文件,可能是一个简单的示例应用,用于演示如何监听ListView滚动并实现返回顶部的功能。在实际开发中,我们通常会添加一个悬浮按钮,当用户滚动到一定距离时让它显示,用户点击即可回到...

    Android 完美的listview自动循环滚动

    总之,"Android 完美的listview自动循环滚动"涉及到的关键技术点包括自定义Adapter、监听ListView滚动事件、数据的取模计算以及性能优化。通过这些技术,我们可以创建出一个流畅且具有循环滚动功能的ListView,为...

    解决Android ListView滚动布局错位

    综上所述,解决Android ListView滚动布局错位的关键在于正确地管理视图类型,并在`getView()`方法中确保视图的复用符合数据的类型。同时,实现多布局时要保持逻辑清晰,避免混淆不同类型的视图。通过这些方法,你...

    android listview 自动往上滚动

    综上所述,实现"android listview 自动往上滚动"的效果,需要掌握Android的ListView滚动机制、动画系统、监听事件以及性能优化等多方面的知识。通过对这些知识点的深入理解和实践,开发者可以创造出更加生动有趣的...

    listview通用adapter

    在Android开发中,ListView是一种常用的组件,用于展示可滚动的列表数据。通用Adapter是ListView高效运作的关键,它允许我们以一种灵活的方式绑定不同类型的数据显示在ListView的各个项中。本教程将详细介绍`...

    Android自定义adapter的listview

    以上就是关于“Android自定义adapter的listview”的主要知识点。自定义Adapter是Android开发中的核心技能之一,掌握好这一技巧,能帮助我们实现各种复杂的界面效果。通过不断实践和优化,我们可以在保证性能的同时,...

    ListView刷新和监听滚动事件选项事件的例子

    例如,当你从网络获取新数据并更新到Adapter的数据源后,调用这个方法,ListView会自动刷新显示最新的内容。 接下来是监听ListView的滚动事件。要实现这一功能,我们需要在Activity或Fragment中添加一个...

    Android ListView adapter不同布局

    "Android ListView adapter不同布局"这个主题就是关于如何在ListView中实现这样的功能。 首先,我们了解ListView的工作原理。ListView依赖于Adapter来填充数据。Adapter就像一个桥梁,连接数据源(如ArrayList)和...

    listview自动滚动

    例如,当ListView滚动到最后一项时,应该重新滚动到第一项,实现无缝循环的效果。这需要结合`OnScrollListener`监听滚动事件,并在必要时调整滚动方向。 此外,为了提高用户体验,我们还可以添加动画效果,比如淡入...

    通过控制焦点横向滚动listview 不是单条滚动,以及listview之间的联动效果

    实现ListView之间的联动效果,即当一个ListView滚动时,其他ListView也相应滚动,需要监听滚动事件并同步滚动状态。具体操作如下: - 创建一个ScrollListener类,重写onScroll()和onScrollStateChanged()方法。 -...

    Android 实现ListView滚动到底部自动加载数据

    总之,实现Android ListView滚动到底部自动加载数据涉及到的主要步骤包括:设置适配器、监听滚动事件、判断是否滚动到底部、加载新数据和更新列表。这个过程需要对Android的基础组件和数据操作有深入的理解,同时也...

Global site tag (gtag.js) - Google Analytics