ListView поддерживать состояние с помощью тега? - PullRequest
0 голосов
/ 29 февраля 2012

Очевидно, у моего мышления есть какой-то недостаток, поскольку он работает неправильно. По сути, я пытаюсь решить эту проблему: просмотр списка с флажком

В ответ люди предложили создать глобальную структуру данных для хранения состояния, что имело смысл. Однако я подумал, что если я использую шаблон ViewHolder, я мог бы использовать тег в качестве структуры для хранения информации о состоянии?

cbox.setOnClickListener(new OnClickListener() {
    public void onClick(View v)
    {
        P tag = (P) ((View) v.getParent()).getTag();
        if(tag.cbox.isChecked())
            tag.cbox.setChecked(true);
        else
            tag.cbox.setChecked(false);
        //tag.cbox.toggle();
        Log.d("YoYo", Boolean.toString(tag.cbox.isChecked()));
    }
});

Приведенный выше код не переключал мой флажок в строках. Что я сделал не так?

Обновление: Вместо того, чтобы переключаться, вручную, если оператор, казалось, работал. Тем не менее, я сталкиваюсь с другой проблемой, когда проверенное состояние портится после прокрутки в разные места. Это почему? Если я установлю проверенное состояние в tag.cbox, не будет ли проверенное состояние уникальным только для этого объекта?


Обновление 2: я последовал совету другого и получил рабочую версию, но мне все еще интересно, почему setTag / getTag не работает?

Рабочая:

   public View getView(final int position, View view, ViewGroup parent)
    {
        Plurker tag = getItem(position);
        if (view == null)
            view = adapterLayoutInflater.inflate(R.layout.adapter, null);                
        tag.avatar = (ImageView) view.findViewById(R.id.imgAvatar);
        tag.cbox = (CheckBox) view.findViewById(R.id.cBox);
        tag.cbox.setOnCheckedChangeListener(new OnCheckedChangeListener()
        {
            public void onCheckedChanged(CompoundButton btn, boolean isChecked)
            {
                int pos = position;
                Plurker p = getItem(pos);
                p.isChecked = isChecked;
                Log.d("PLURK", "Listener:" + p.toString());
            }
        });
        tag.update(getItem(position));
        Log.d("PLURK", tag.cbox.getText() + ":" + Integer.toString(position));

        return view;
    }

Не работает:

public View getView(final int position, View view, ViewGroup parent)
{
    Plurker tag = getItem(position);
    if (view == null)
    {
        view = adapterLayoutInflater.inflate(R.layout.adapter, null);
        tag.avatar = (ImageView) view.findViewById(R.id.imgAvatar);
        tag.cbox = (CheckBox) view.findViewById(R.id.cBox);    
        tag.cbox.setOnClickListener(new View.OnClickListener() {           
            public void onClick(View arg0)
            {
                int pos = position;
                Plurker p = getItem(pos);
                p.isChecked = !p.isChecked;
                Log.d("PLURK", "Listener:" + p.toString());
            }
        });
        view.setTag(tag);
    }
    else
        tag = (Plurker) view.getTag();

    tag.update(getItem(position));
    Log.d("PLURK", tag.cbox.getText() + ":" + Integer.toString(position));

    return view;
}

В «не работающей» версии мне нужно использовать onClick вместо события onCheckedChanged, потому что при повторном появлении представления из скрытого оно вызывало прослушиватель событий, поэтому он ложно срабатывал.

1 Ответ

1 голос
/ 02 марта 2012

Вы каждый раз надуваете новое представление или используете переданный convertView?

Обычно Адаптер пытается перезапустить представления, создавая их достаточно, чтобы обеспечить плавную прокрутку.Существующие переработанные представления передаются как convertView.Вы можете либо раздувать и возвращать новое представление каждый раз (дорого), либо просто переконфигурировать convertView (если он существует) в зависимости от позиции.Если вы перерабатываете, вам необходимо заново установить все атрибуты вида, так как нет никакой гарантии, что полученный вами переработанный вид был тем же, который использовался для этой позиции в прошлом.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...