【问题标题】:ConvertView being passed in as a view that's still on screenConvertView 作为仍在屏幕上的视图传入
【发布时间】:2011-06-07 22:09:15
【问题描述】:

在我的自定义 ListAdapter 中,第一次调用 GetView() 时,convertView 作为 NULL 传入,但第二次作为第一次创建的视图传入。我的 ListView 有 4 行,所有 4 行同时在屏幕上。从文档来看,convertView 似乎应该是一个已经创建并且现在已经从屏幕上滚动出来的视图。我希望 convertView 全部为空 4 次,以便它创建/膨胀 4 个单独的视图。第一次调用 getView 后我应该有一个 convertView 吗?谢谢。

在 OnCreate() 中:

    Cursor questions = db.loadQuestions(b.getLong("categoryId"), inputLanguage.getLanguageId(), outputLanguage.getLanguageId());
    startManagingCursor(questions);

    ListAdapter adapter = new QuestionsListAdapter(this, questions);

    ListView list = (ListView)findViewById(R.id.list1);
    setListAdapter(adapter);

适配器类

private class QuestionsListAdapter extends BaseAdapter implements  ListAdapter{

    private Cursor c;
    private Context context;

    public QuestionsListAdapter(Context context, Cursor c) {
        this.c = c;
        this.context = context;
    }

    public Object getItem(int position) {
        c.moveToPosition(position);
        return new Question(c);
    }

    public long getItemId(int position) {
        c.moveToPosition(position);
        return new Question(c).get_id();
    }

    @Override
    public int getItemViewType(int position) {

        Question currentQuestion = (Question)this.getItem(position);
        if (currentQuestion.getType().equalsIgnoreCase("text"))
            return 0;
        else if (currentQuestion.getType().equalsIgnoreCase("range"))
            return 0;
        else if (currentQuestion.getType().equalsIgnoreCase("yesNo"))
            return 2;
        else if (currentQuestion.getType().equalsIgnoreCase("picker"))
            return 0;
        else if (currentQuestion.getType().equalsIgnoreCase("command"))
            return 0;
        else if (currentQuestion.getType().equalsIgnoreCase("datePicker"))
            return 0;
        else if (currentQuestion.getType().equalsIgnoreCase("diagram"))
            return 0;
        else
            return -1;
    }

    @Override
    public int getViewTypeCount() {
        return 7;
    }

    public int getCount() {
        return c.getCount();
    }

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

        Question currentQuestion = (Question)this.getItem(position);

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.question_row_text, null);
        }
        //setup cell

        return convertView;
    } 
}

【问题讨论】:

  • 您对文档的分析是正确的。您确定所有四个视图都适合屏幕吗?你能发布一些代码/XML吗?
  • 我用代码编辑...我没有添加它,因为一旦调用 GetView() 行为就很明显...所以我认为它与我的 GetView( ) 代码...
  • 此外,列表基本上加载正常......我在屏幕上看到所有 4 行。
  • 我将其发布为评论,而不是答案,因为我在这里仅凭记忆,但是:我认为这与我所看到的行为一致。你让代码运行完成了吗?如果我没记错的话,GetView 将为要显示的每一行调用两次。我认为第一组调用是为了布局目的,第二组返回实际显示的视图。无论哪种情况,您的代码都应该做同样的事情(同样的事情,只需使用传入的 ConvertView。)
  • @Dan - 我想你实际上已经明白了......看起来它一次通过了所有 4 个,后 3 个传入了第一个创建的 convertView。但是,它再次运行了所有 4 个......这一次,它没有为后 3 个传递一个 convertView。所以这是创建后 3 个视图的时间。非常感谢!

标签: android listview convertview


【解决方案1】:

如果我没记错的话,GetView 将为要显示的每一行调用两次。我认为第一组调用是为了布局目的,第二组返回实际显示的视图。第二组调用返回的视图应该与第一组调用中返回的视图相同。

在任何情况下,您的代码都不应该关心它是被调用来进行布局还是显示。在几乎所有情况下,如果convertView 不为空,那么通常应该返回convertView;否则,您应该返回一个新视图。

【讨论】:

  • getView() 通常不会在显示的每行中多次调用,除非 getView() 中的某些内容使您的布局无效。发生这种情况的一种非常常见的方法是,如果您在具有 layout_width='wrap_content' 的 TextView 上调用 TextView.setText(),或者如果 TextView 的高度将由于 setText() 而发生变化
  • 刚刚观看了链接到问题 cmets 的视频,对于前 3 个列表项,这似乎也发生在正常情况下。不过我不确定我是否完全理解。
【解决方案2】:

说实话,我看不出您的代码有什么问题。您可能想尝试扩展 CursorAdapter 并仅覆盖一些方法,以便它可以为您管理光标。

【讨论】:

    【解决方案3】:

    快进到 2014 年,我也遇到了同样的问题……这篇文章中的解决方案都不适合我。当我观看上述答案和 cmets 中引用的 Google I/O 视频时,答案(对于我的特定情况)在大约 19 分钟时立即变得明显......

    从 GETVIEWTYPECOUNT() 返回的数字必须在适配器的整个生命周期中保持不变!!!!

    我创建了一个适配器,它可以动态地拥有任意数量的视图/数据类型...并且我的 getViewTypeCount() 方法返回了当前视图类型的数量...所以,如果我添加了一个新的数据类型到返回值会改变的适配器。

    将其设为常数解决了我的问题。希望这对未来的其他人也有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-24
      • 2021-03-10
      • 2021-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多