ConvertView 作为仍在屏幕上的视图传入

发布于 2024-11-14 18:46:55 字数 2556 浏览 2 评论 0原文

在我的自定义ListAdapter中,第一次调用GetView()时,convertView作为NULL传入,但第二次它作为第一次创建的视图传入。我的 ListView 有 4 行,所有 4 行同时显示在屏幕上。从文档来看,convertView 似乎应该是一个已经创建的视图,现在已经滚动到屏幕之外。我预计 ConvertView 4 次都为 null,这样它就会创建/膨胀 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;
    } 
}

In my custom ListAdapter, the first time that GetView() is called, convertView is passed in as NULL, but the second time it is passed in as the view that was created the first time. My ListView has 4 rows, and all 4 are on the screen at the same time. From the documentation, it seems that convertView should be a view that was already created and has now been scrolled off the screen. I expected convertView to be null all 4 times, so that it would create / inflate 4 separate views. Am I supposed to have a convertView after the first call to getView? Thanks.

In 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);

Adapter class

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;
    } 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

思念满溢 2024-11-21 18:46:55

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

无论如何,您的代码不应该关心它是否被调用用于布局或显示。几乎在所有情况下,如果 convertView 为非 null,则通常应返回该 convertView;否则,您应该返回一个新的视图。

If I remember right, GetView will be called twice for each row that's to be displayed. I think that the first set of calls is done for layout purposes, and the second set returns the views that will actually be displayed. It makes sense that the second set of calls should return the same Views that were returned in the first set of calls.

In any case, your code should not care whether it's being called for layout or display. In almost all situations, if the convertView is non-null, then normally that convertView should be returned; otherwise, you should return a new View.

诗酒趁年少 2024-11-21 18:46:55

老实说,我看不出你的代码有什么问题。您可能想尝试扩展 CursorAdapter 和只需重写一些方法,以便它可以为您管理光标。

To be honest I can't see much wrong with your code. You might want to try extending CursorAdapter and just overriding a few methods so that it can manage the cursor for you.

羅雙樹 2024-11-21 18:46:55

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

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

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

使它成为一个常数解决了我的问题。希望这将来也能帮助其他人。

Fast forward to 2014 and I was having the same problem... None of the solutions in this post worked for me. As I was watching the Google I/O video referenced in above answers and comments, the answer (for my particular case) became immediately obvious at about the 19 minute mark...

THE NUMBER RETURNED FROM GETVIEWTYPECOUNT() MUST REMAIN CONSTANT THROUGHOUT THE LIFE OF THE ADAPTER!!!!

I had created an adapter that could dynamically have any number of types of views/data... and my getViewTypeCount() method returned the current number of view types... so, if I ever added a new data type to the adapter that return value would change.

Making it a constant number fixed my problem. Hopefully this will help other people in the future as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文