`
zlrvone
  • 浏览: 3003 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

android自定义adapter 滑动屏幕时 进度条显示混乱

阅读更多
    很久之前想找一份做android的工作 由于遇到了一份虽不是android 但其他方面还都比较满意的工作后 放弃了android梦 如今 公司也开始拓展了android项目 打听了一下 之前的公司也开始全面改做android 看来是都逃不过市场的趋向 有种殊途同归之感
    言归正传 在做一个小的练习(断点下载)时遇到了如下情况 需要自定义adapter动态添加listview listview中有两个固定控件 TextView 和 一个button 点击button 在listview中动态(addview)添加一个进度条 用来显示下载的进度 在一页的显示中没有问题 但是当翻页显示到下一页时 会出现进度条混乱的情况 并且没有规律 产生的原因要了解下自定义adapter的显示特性 在网上搜一下就可以找到基本原理了 不再重复 这里说一下其他文章没有涉及到的东西 下面是我的程序打出的log 在getView()中添加语句:
		System.out.println("In GETVIEW ---- " +  convertView.toString() + "---- position ---- " + position);

In GETVIEW ---- android.widget.LinearLayout@ 44f1fdd8 ---- position ---- 0
In GETVIEW ---- android.widget.LinearLayout@ 44f28828 ---- position ---- 1
In GETVIEW ---- android.widget.LinearLayout@ 44f2c1a8 ---- position ---- 2
In GETVIEW ---- android.widget.LinearLayout@ 44f2fb28 ---- position ---- 3
In GETVIEW ---- android.widget.LinearLayout@ 44f334a8 ---- position ---- 4
In GETVIEW ---- android.widget.LinearLayout@ 44f36e60 ---- position ---- 5
In GETVIEW ---- android.widget.LinearLayout@ 44f3a7e0 ---- position ---- 6
In GETVIEW ---- android.widget.LinearLayout@ 44f3e160 ---- position ---- 7
In GETVIEW ---- android.widget.LinearLayout@ 44f1fdd8 ---- position ---- 8
In GETVIEW ---- android.widget.LinearLayout@ 44f4bde0 ---- position ---- 9
In GETVIEW ---- android.widget.LinearLayout@ 44f28828 ---- position ---- 10
In GETVIEW ---- android.widget.LinearLayout@ 44f2c1a8 ---- position ---- 11
In GETVIEW ---- android.widget.LinearLayout@ 44f2fb28 ---- position ---- 12
In GETVIEW ---- android.widget.LinearLayout@ 44f334a8 ---- position ---- 13

    在我的modis上 可以显示出7个listview 也就是在position ---- 8位置的listview是需要绘制出来的新条目 我们看到新绘制的listview用了一个新的convertView对象 position ---- 9也一样是新的convertView对象 从 position ---- 10开始往后 就是按照顺序拿出缓存中的1 2 3 4来绘制listview 这样我看似乎看到了一个解决问题的办法 即可以预想到有进度条的listview何时在缓存中被取出 那样我们就可以去掉progressbar 本人也试验过这个想法 没有成功 原因如下 重新来看一组log
In GETVIEW ---- android.widget.LinearLayout@ 44f89f98 ---- position ---- 0
In GETVIEW ---- android.widget.LinearLayout@ 44f8c6b8 ---- position ---- 1
In GETVIEW ---- android.widget.LinearLayout@ 44f39598 ---- position ---- 2
In GETVIEW ---- android.widget.LinearLayout@ 44f01b40 ---- position ---- 3
In GETVIEW ---- android.widget.LinearLayout@ 44f769e8 ---- position ---- 4
In GETVIEW ---- android.widget.LinearLayout@ 44f4dfa8 ---- position ---- 5
In GETVIEW ---- android.widget.LinearLayout@ 44ed7db0 ---- position ---- 6
In GETVIEW ---- android.widget.LinearLayout@ 44f550c0 ---- position ---- 7
In GETVIEW ---- android.widget.LinearLayout@ 44f39598 ---- position ---- 8
In GETVIEW ---- android.widget.LinearLayout@ 44f8c6b8 ---- position ---- 9
In GETVIEW ---- android.widget.LinearLayout@ 44f89f98 ---- position ---- 10
In GETVIEW ---- android.widget.LinearLayout@ 44f9d3e8 ---- position ---- 11
In GETVIEW ---- android.widget.LinearLayout@ 44f01b40 ---- position ---- 12
In GETVIEW ---- android.widget.LinearLayout@ 44f4dfa8 ---- position ---- 13

    这组log是在快速拖动滚动条时的log 发现当快速滚动时 position ---- 8在绘制时直接拿到的是position ---- 2的convertView 而下面的9 10 11位置上用到的convertView也是没有规律可循的 每次快速的滚动条目时 log也是不一样的
    我的猜测是这样的 在缓慢拖动时 第一个显示的条目由可见到不可见 并且是逐渐的不可见 存在这样的情况 第一个条目的一半不可见 此时必将有一个新的条目要绘制出一半 这样系统给我们提供了两个新的convertView 来绘制显示 以维持这个缓存 而当快速拖动时 上面的条目会快速的被掩盖 马上进入缓存 以备下面条目的显示 不知道这样理解是否正确 希望了解这个机制的人做下纠正
    所以现在的可以总结为 我们不知道缓存中convertView何时被拿出来显示 也不知道哪个convertView有progressbar这个控件 所以我想到了一个办法 去掉所有控件后 重新加载控件 但是在做convertView = listContainer.inflate(R.layout.itemlist, null);这个操作的时候 相当于重新new了一个convertView 这样就违背了缓存机制节省资源的意图 因此最后想到的办法是在getview函数中 每次从缓存中拿出convertView时 都检查是否有progressbar这个控件 有的话 去掉此控件 再重新绘制progressbar 主要代码如下:
		if (convertView == null) {
			listitemview = new ListItemView();
			convertView = listContainer.inflate(R.layout.itemlist, null);
			convertView.setTag(listitemview);

		} else {
//主要部分
			listitemview = (ListItemView) convertView.getTag();
			LinearLayout m_layout = ((LinearLayout) convertView);
			for (int i = 0; i < m_layout.getChildCount(); i++) {
				if (m_layout.getChildAt(i) instanceof ProgressBar) {
					m_layout.removeViewAt(i);
				}
			}
		}

    这样就可以解决问题了
    在解决问题的过程中 上网查了很多资料 但是没有找到很好解决这个问题的方法 于是在这里记录一下自己解决问题的过程 也算记笔记了 当然这个办法肯定不是最好的 每次需要循环listview中的所有控件 当然可以减少循环的几率 判断convertView中的控件数目 我也想过 如果progressbar不是动态加载进去(addview) 而是在R.layout.itemlist中定义 默认设为不可见状态 每次调用getview时 检查是否需要变成可见状态 也是可以实现的 由于这个程序是要断点下载 所以检查过程就是去看数据库中是否有下载的记录即可 不过我没有做尝试
    ps:我还真证明不了这个是我写的。。。。

同步于CMD100博客
1
1
分享到:
评论
2 楼 aboutibm 2013-08-24  
这么做可以解决问题,但是有点麻烦了,简单点的解决办法为:
if(......){
    holder.downloadProgressBar.setProgress(value);
    holder.downloadProgressBar.setVisibility(ProgressBar.VISIBLE);
}else{
    holder.downloadProgressBar.setProgress(0);
    holder.downloadProgressBar.setVisibility(ProgressBar.INVISIBLE);
}

即符合条件的显示,不符合条件的隐藏即可解决问题
1 楼 w1041966246 2012-09-14  
哥们 能给点代码研究研究吗? 我现在正纠结这问题呢? 网上找的资料都是你这一篇啊。

相关推荐

Global site tag (gtag.js) - Google Analytics