У меня есть список, в котором каждая строка содержит флажок и текстовое представление, также у меня есть кнопка, которая должна проверять/снимать все флажки в списке, однако я не смог для достижения этого с помощью флажков OUTSIDE на экране, только с видимыми. И если я хорошо понял, это происходит из-за того, что элементы вне экранов не существуют, они перерабатываются для создания новых строк при прокрутке, вызывая нулевые указатели/из ошибок индекса при попытке проверить/получить доступ к флажкам за пределами экрана.Как проверить все флажки в ListView
I Googled для решений, но до сих пор ничего не работало.
Как я могу это решить?
Вот адаптер:
public class AlumnoArrayAdapter<T> extends BaseAdapter{
Context mContext;
LayoutInflater mInflater;
ArrayList<T> mList;
ArrayList<Alumno> alumno;
boolean verEstadisticas;
SparseBooleanArray mSparseBooleanArray;
public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) {
//TODO Auto-generated constructor stub
this.alumno = alumno;
this.verEstadisticas = verEstadisticas;
this.mContext = context;
mInflater = LayoutInflater.from(mContext);
mSparseBooleanArray = new SparseBooleanArray();
mList = new ArrayList<T>();
this.mList = list;
}
public ArrayList<T> getCheckedItems() {
ArrayList<T> mTempArry = new ArrayList<T>();
for(int i=0;i<mList.size();i++) {
if(mSparseBooleanArray.get(i)) {
mTempArry.add(mList.get(i));
}
}
return mTempArry;
}
public int getCount() {
return mList.size();
}
public Object getItem(int position) {
return mList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
}
TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
tvTitle.setText(mList.get(position).toString());
CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable);
mCheckBox.setTag((Integer) position);
mCheckBox.setChecked(mSparseBooleanArray.get(position));
mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
if(verEstadisticas){
mCheckBox.setVisibility(View.GONE);
}
mCheckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Integer position = (Integer) cb.getTag();
alumno.get(position).setChecked(cb.isChecked());
}
});
return convertView;
}
OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSparseBooleanArray.put((Integer) buttonView.getTag(), isChecked);
}
};
}
Если больше кода необходим, пожалуйста, дайте мне знать.
Поблагодарили бы за любую помощь.
Заранее благодарен!
EDIT: Есть решение !, модифицированный адаптер:
public class AlumnoArrayAdapter<T> extends BaseAdapter{
Context mContext;
LayoutInflater mInflater;
ArrayList<T> mList;
ArrayList<Alumno> alumno;
boolean verEstadisticas;
SparseBooleanArray mSparseBooleanArray;
boolean checarTodo = false;
public AlumnoArrayAdapter(Context context, ArrayList<T> list, ArrayList<Alumno> alumno, boolean verEstadisticas) {
//TODO Auto-generated constructor stub
this.alumno = alumno;
this.verEstadisticas = verEstadisticas;
this.mContext = context;
mInflater = LayoutInflater.from(mContext);
mSparseBooleanArray = new SparseBooleanArray();
mList = new ArrayList<T>();
this.mList = list;
}
public ArrayList<T> getCheckedItems() {
ArrayList<T> mTempArry = new ArrayList<T>();
for(int i=0;i<mList.size();i++) {
if(mSparseBooleanArray.get(i)) {
mTempArry.add(mList.get(i));
}
}
return mTempArry;
}
public int getCount() {
return mList.size();
}
public Object getItem(int position) {
return mList.get(position);
}
public long getItemId(int position) {
return position;
}
public void checkAll(){
for(int x = 0; x < alumno.size(); x++){
alumno.get(x).setChecked(!alumno.get(x).isChecked());
}
}
public View getView(final int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
}
TextView tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
tvTitle.setText(mList.get(position).toString());
CheckBox mCheckBox = (CheckBox) convertView.findViewById(R.id.chkEnable);
mCheckBox.setTag((Integer) position);
mCheckBox.setChecked(alumno.get(position).isChecked());
if(verEstadisticas){
mCheckBox.setVisibility(View.GONE);
}
mCheckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
//Alumno Alumno = (Alumno) cb.getTag();
Integer position = (Integer) cb.getTag();
alumno.get(position).setChecked(cb.isChecked());
}
});
return convertView;
}
}
Это работал в совершенстве. Просто немного изменили то, что вы точно предложили. Не удалось использовать логическое свойство для флага «checkAll». Вместо этого, в методе «checkAll» только что изменили логические данные для флажка в структуре данных и просто вызвали notifyDataSetChanged, чтобы перерисовать список, и вместо того, чтобы использовать mSparseBooleanArray для установки состояния флажков, я использовал ArrayList, где храню данные, которые мне нужны. Вы можете увидеть измененный адаптер в OP, отредактированный с ним. Еще раз спасибо! – Moko