gpt4 book ai didi

android - 快速滚动时以错误的位置调用 getView

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:24:34 31 4
gpt4 key购买 nike

这里是相当新的 Android 开发者。

我遇到了一个奇怪的问题,我不确定如何解决。我在这里阅读了很多问题,听起来它们与我遇到的问题相同,但他们问题的解决方案似乎永远不适用于这里发生的事情。

我使用扩展 BaseAdapter 并使用 View 持有者的单独类设置了自定义 listView(我通过查看自定义 ListView 的各种不同示例来设置它)。它有一个 TextView 、一个按钮、一个进度条和一个图像按钮,这些项目是根据用于下载文件的 AsyncTask 隐藏/更改的。

当我缓慢滚动列表时,一切正常。当我快速向上/向下滚动列表时,就好像列表中某些单元格的 View 被重新分配给其他单元格。

我将这一行放在适配器类中“getView”方法的顶部:

    @Override
public View getView(final int pos, View convertView, ViewGroup parent)
{
Log.i("ks3","getView called, position is " + pos);

我的列表中有 7 个项目,其中 6 个适合屏幕。当它第一次显示时,我在我的日志中看到了这个:

getView called, position is 0
getView called, position is 1
getView called, position is 2
getView called, position is 3
getView called, position is 4
getView called, position is 5

当我慢慢向下滚动到下一个项目时,接下来打印出来:

getView called, position is 6

当我向上滚动时,这是:

getView called, position is 0

慢慢下降和上升会完美地产生这些结果。

当我开始快速来回滚动时,它会多次打印这条消息,主要显示 6 和 0 作为位置,但偶尔我也会看到这些:

getView called, position is 1
getView called, position is 5

位置 1 和 5 不应该被调用,因为它们总是在屏幕上。就好像 getView 搞得一团糟。同时,正如我之前所说,我的列表看起来很奇怪。图像按钮将在它们不应该出现的位置上移或下移。

如果我回到平滑滚动,我再次看到位置为 0 和 6。

老实说,我不确定如何解决这个问题。我想也许我可以限制您滚动列表的速度,但一直无法找到任何有用的东西。

谢谢!

编辑:我想更新关于这个问题的一些事情。首先,从这里的评论和 listView 上的 Google 视频中,我注意到 getView 可以被调用用于其他事情,而不是我想象的,比如测量,所以我不应该 panic 我最初认为是我的问题的一部分(因为我认为 getView 被错误的位置调用)。

其次,我多次看到“在适配器中缓存 View ”是一个非常糟糕的主意。我不太清楚这意味着什么,但我很确定这是我做错的事情之一(我保存了一个按钮、progressBar、imageButton 的实例...)。

那个,以及我在 getView 之外更新 View 并且我不使用 notifyDataSetChanged() 的事实;这些加在一起可能会导致一些奇怪的事情发生。

最佳答案

ListView 在屏幕上的不同位置重复使用 View 是正确的。这是一种通过不一直分配新 View 来保持内存使用合理和快速的优化。

很可能您没有正确使用 LiewView。 watch this talk on how to properly use ListView了解整个故事,但这里是重点:

  1. “位置”是指您的数据在适配器列表中的位置。如果您的适配器数据在一个数组中,这将是该数组的索引。
  2. “ID”是指数据本身的值。如果你有一个名字列表并对它们进行排序,它们的位置会改变,但它们的 ID 不会。
  3. “索引”是指 View 相对于可视屏幕区域的相对位置。你可能永远不需要这个。
  4. 不要在适配器的 getView() 方法之外操作 View (或尝试缓存它们),否则会出现奇怪的行为。
  5. 如果对 getView(int, View, ViewGroup) 的调用提供了一个 View 实例,则填充它的字段而不是扩充全新的 View 。假设您已正确实现 getItemType(),您将始终获得正确的 View 类型以重新填充。
  6. 让您的 getView() 方法尽可能快,并且只在其他线程上做繁重的工作。
  7. 仅仅因为名为 getView() 的容器并不一定意味着数据会被显示。该框架将这些用于测量目的。由于工作可能会被丢弃,这是确保 getView() 尽可能快的另一个原因。
  8. 当您需要在屏幕上显示的数据出现问题时,即您的下载已完成,此时您将调用 notifyDataSetChanged()。不要直接摆弄 View ,它们将在重绘时在下一个 UI 循环中填充。

刚刚花了几天时间修改了一个天真的实现的ListView,我感受到了你的痛苦。不过,结果是值得的!

关于android - 快速滚动时以错误的位置调用 getView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9712494/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com