很久之前想找一份做android的工作 由于遇到了一份虽不是android 但其他方面还都比较满意的工作后 放弃了android梦 如今 公司也开始拓展了android项目 打听了一下 之前的公司也开始全面改做android 看来是都逃不过市场的趋向 有种殊途同归之感
言归正传 在做一个小的练习(断点下载)时遇到了如下情况 需要自定义adapter动态添加listview listview中有两个固定控件 TextView 和 一个button 点击button 在listview中动态(addview)添加一个进度条 用来显示下载的进度 在一页的显示中没有问题 但是当翻页显示到下一页时 会出现进度条混乱的情况 并且没有规律 产生的原因要了解下自定义adapter的显示特性 在网上搜一下就可以找到基本原理了 不再重复 这里说一下其他文章没有涉及到的东西 下面是我的程序打出的log 在getView()中添加语句:
在我的modis上 可以显示出7个listview 也就是在position ---- 8位置的listview是需要绘制出来的新条目 我们看到新绘制的listview用了一个新的convertView对象 position ---- 9也一样是新的convertView对象 从 position ---- 10开始往后 就是按照顺序拿出缓存中的1 2 3 4来绘制listview 这样我看似乎看到了一个解决问题的办法 即可以预想到有进度条的listview何时在缓存中被取出 那样我们就可以去掉progressbar 本人也试验过这个想法 没有成功 原因如下 重新来看一组log
这组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 主要代码如下:
这样就可以解决问题了
在解决问题的过程中 上网查了很多资料 但是没有找到很好解决这个问题的方法 于是在这里记录一下自己解决问题的过程 也算记笔记了 当然这个办法肯定不是最好的 每次需要循环listview中的所有控件 当然可以减少循环的几率 判断convertView中的控件数目 我也想过 如果progressbar不是动态加载进去(addview) 而是在R.layout.itemlist中定义 默认设为不可见状态 每次调用getview时 检查是否需要变成可见状态 也是可以实现的 由于这个程序是要断点下载 所以检查过程就是去看数据库中是否有下载的记录即可 不过我没有做尝试
ps:我还真证明不了这个是我写的。。。。
同步于CMD100博客
言归正传 在做一个小的练习(断点下载)时遇到了如下情况 需要自定义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博客