Подтвердить что ты не робот

ListView повторно использует представления, когда... Я не хочу, чтобы он

У меня есть ListView, каждый из item которого содержит ToggleButton. После того, как я переключу его, а затем прокручиваю вверх или вниз, ListView перерабатывает представления, поэтому некоторые из других зеркалируют проверенное состояние ToggleButton. Я не хочу этого. Как я могу предотвратить это?

4b9b3361

Ответ 1

Android перерабатывает элементы списка для повышения производительности. Настоятельно рекомендуется повторно использовать их, если вы хотите, чтобы ListView прокручивался плавно.

Для каждого элемента списка вызывается функция getView вашего адаптера. Там, где вы должны назначить значения для элемента, который запрашивает ListView.

Взгляните на этот пример:

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    ViewHolder holder = null;

    if ( convertView == null )
    {
        /* There is no view at this position, we create a new one. 
           In this case by inflating an xml layout */
        convertView = mInflater.inflate(R.layout.listview_item, null);  
        holder = new ViewHolder();
        holder.toggleOk = (ToggleButton) convertView.findViewById( R.id.togOk );
        convertView.setTag (holder);
    }
    else
    {
        /* We recycle a View that already exists */
        holder = (ViewHolder) convertView.getTag ();
    }

    // Once we have a reference to the View we are returning, we set its values.

    // Here is where you should set the ToggleButton value for this item!!!

    holder.toggleOk.setChecked( mToggles.get( position ) );

    return convertView;
}

Обратите внимание, что ViewHolder - это статический класс, который мы используем для повторного использования этого представления. Его свойства - это виды, которые имеют элементы вашего списка. Он объявлен в вашем адаптере.

static class ViewHolder{
    ToggleButton toggleOk;
}

mToggles объявляется как частное свойство в вашем адаптере и устанавливается с помощью общедоступного метода, например:

public void setToggleList( ArrayList<Boolean> list ){
        this.mToggles = list;
        notifyDataSetChanged();
    }

Дополнительную информацию см. в других пользовательских примерах ListView.

Надеюсь, что это поможет.

Ответ 2

Добавьте два адаптера к вашему адаптеру.

@Override

public int getViewTypeCount() {                 

    return getCount();
}

@Override
public int getItemViewType(int position) {

    return position;
}

Ответ 3

Вы можете использовать HashMap для сохранения состояния ваших кнопок:

 private Map<Integer,Boolean> listMapBoolean = new HashMap<Integer,Boolean>();


 toggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if (isChecked) {
                            listMapBoolean.put(position, true);
                        } else {
                            listMapBoolean.put(position, false);
                        }
                    }
                });

и после раздувания представления вы читаете HashMap, чтобы убедиться, что он был отмечен или нет:

 for (Entry<Integer, Boolean> entry : listMapBoolean.entrySet()) {
                if (entry.getKey().equals(i)) {
                    if(entry.getValue()) {
                        System.out.println("ToggleButton is checked!");
                    } else {
                        System.out.println("ToggleButton is not checked!");
                    }
                }
            }

Не уверен, что это поможет на вашем пути. У меня также были проблемы с переработкой моего EditText в моем ListView.

Ответ 4

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