2016-11-08 2 views
1

У меня есть listView в моем приложении. Для каждого элемента в listView он имеет коммутатор. Раньше я реализовал onClickListener для коммутатора в методе getView listView Adapter. Однако я обнаружил, что, хотя он работает, когда пользователь нажимает на коммутатор, он не работает, когда пользователь переходит на коммутатор. Затем я пытаюсь изменить onClickListener на onCheckedChangeListener. Он работает, когда пользователь щелкает или перемещается на коммутаторе, однако, когда я просматриваю списокView, чтобы этот элемент исчезал, я обнаружил, что выбранный переключатель, который был первоначально проверен, не установлен.Android: Включить OnCheckedChangeListener в адаптер ListView

Не могли бы вы помочь? Ниже приведен код для метода GetView в ListView адаптер:

@Override 
public View getView(final int position, View convertView, final ViewGroup parent) { 
    class viewHolder { 
     public TextView tvSceneName; 
     public Switch swSelectSwitch; 
    } 
    final viewHolder holder; 

    final View v = convertView; 

    // Use ViewHolder to avoid findViewById each time the user scroll 
    if (convertView == null) { 
     holder = new viewHolder(); 
     convertView = mInflater.inflate(R.layout.scene_list_element, parent, false); 
     holder.tvSceneName = (TextView) convertView.findViewById(R.id.tvSceneName); 
     holder.swSelectSwitch = (Switch) convertView.findViewById(R.id.swScene); 
     convertView.setTag(holder); 
    } else { 
     holder = (viewHolder) convertView.getTag(); 
    } 


    if(holder.swSelectSwitch != null) { 

     // Set the switch to correct on/off status 
     holder.swSelectSwitch.setChecked(mDataSource.get(position).get_isOn()); 

     // Set up On checked change listener for the switch 
     holder.swSelectSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) { 

       // Set the new status to arraylist 
       Switch sw = (Switch) v.findViewById(R.id.swScene); 
       MainActivity.sceneArrayList.get(position).set_isOn(sw.isChecked()); 

     }); 
    } 
} 

EDIT: На следующем испытании я нашел там ошибка в моем добавляемого onCheckChangedListener (потому что я скопировал код из onClickListener). Кроме того, я нашел решение, чтобы установить onCheckChangedListener в значение null, прежде чем устанавливать переключатель по коду.

if(holder.swSelectSwitch != null) { 

    // Set the switch to correct on/off status 
    holder.swSelectSwitch.setOnCheckedChangeListener(null); 
    holder.swSelectSwitch.setChecked(mDataSource.get(position).get_isOn()); 

    // Set up On checked change listener for the switch 
    holder.swSelectSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) { 

      // Set the new status to arraylist 
      mDataSource.get(position).set_isOn(isChecked); 

    }); 
} 
+1

Вы используете два списка. У них такая же ссылка? Если нет, вы обновляете другой список, поэтому после прокрутки ясно, почему ваш флажок не обновлен. Другое дело, почему вы не используете параметры из прослушивателя onCheckedChanged вместо использования findviewbyId – Alex

+0

@Alex. Вы правы, я обнаружил, что должен использовать параметры isChecked. Я использую findviewbyId, потому что просто копирую код из onClickedListner. У параметра onClickedListener этот параметр отсутствует. И списки такие же. На самом деле я не совсем понимаю, как использовать listView, когда у него много компонентов и когда источник данных сложный. – eepty

ответ

0

Вы должны удалить строку if(holder.swSelectSwitch != null) {: при прокрутке, взгляды не были уничтожены, но переработаны, так что, когда getView вызывается после прокрутки, то convertView не равно нулю. Когда convertView не является нулевым, вы затем повторно используете созданный вами держатель и помещаете его в тег вида.

1

Точка отсчета ViewHolder состоит в том, что View s перерабатываются.

Вы извлечения отмеченного состояния от mDataSource, но не обновляет его, поэтому, когда View получает переработаны в Switch возвращается в исходное (незарегистрированный) состоянии.

Вы должны обновить состояние в mDataSource, когда происходит изменение:

@Override 
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) { 

    // Set the new status to arraylist 
    MainActivity.sceneArrayList.get(position).set_isOn(isChecked); 

    // updating mDataSource 
    mDataSource.get(position).set_isOn(isChecked); 
} 
Смежные вопросы