ConvertView передается как вид, который все еще на экране - PullRequest
3 голосов
/ 08 июня 2011

В моем пользовательском ListAdapter, при первом вызове GetView (), convertView передается как NULL, но во второй раз он передается как представление, созданное в первый раз.Мой ListView имеет 4 строки, и все 4 находятся на экране одновременно.Из документации видно, что convertView должен быть представлением, которое уже было создано и теперь прокручивалось за пределы экрана.Я ожидал, что convertView будет нулевым все 4 раза, чтобы он создавал / раздувал 4 отдельных представления.Должен ли я иметь convertView после первого вызова getView?Спасибо.

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

Ответы [ 3 ]

3 голосов
/ 16 июня 2011

Если я правильно помню, GetView будет вызываться дважды для каждой строки, которая должна отображаться.Я думаю, что первый набор вызовов сделан для макета, а второй набор возвращает представления, которые на самом деле будут отображаться.Имеет смысл, чтобы второй набор вызовов возвращал те же представления, которые были возвращены в первом наборе вызовов.

В любом случае, вашему коду не должно быть никакого значения, вызывается ли он для макета или для отображения.Почти во всех ситуациях, если convertView не равен нулю, то обычно возвращается convertView;в противном случае вы должны вернуть новый вид.

0 голосов
/ 07 марта 2014

Перенесемся в 2014 год, и у меня возникла та же проблема ... Ни одно из решений в этом посте не помогло мне.Когда я смотрел видео Google I / O, упомянутое в приведенных выше ответах и ​​комментариях, ответ (для моего конкретного случая) сразу стал очевидным примерно через 19 минут ...

ЧИСЛО, ВОЗВРАЩЕННОЕ ИЗ GETVIEWTYPECOUNT ()ДОЛЖЕН ОСТАВАТЬСЯ ПОСТОЯННЫМ В ТЕЧЕНИЕ ЖИЗНИ АДАПТЕРА !!!!

Я создал адаптер, который может динамически иметь любое количество типов представлений / данных ... и мой метод getViewTypeCount () вернул текущее числопросмотреть типы ... так что, если я когда-нибудь добавлю новый тип данных в адаптер, возвращаемое значение изменится.

Устранение проблемы с помощью постоянного числаНадеюсь, это поможет и другим людям в будущем.

0 голосов
/ 08 июня 2011

Если честно, я не вижу ничего плохого в вашем коде. Возможно, вы захотите попробовать расширить CursorAdapter и просто переопределить несколько методов, чтобы он мог управлять курсором за вас.

...