флажок в списке неожиданно проверяется
-
20-09-2019 - |
Вопрос
У меня есть список флажков в списке, привязанном Custom simpleCursorAdapter
.По моему обычаю simpleCursorAdapter
, я переопределил newView
и bindView
с моими модификациями.Мне как-то удалось сделать множественный выбор.Странно то, что после того, как я удаляю любой элемент из своего списка, флажок первого элемента внезапно устанавливается.Как это происходит?Как я могу это решить?
Мой SimpleCursorAdapter
сорт:
public class MyListCursorAdapter extends SimpleCursorAdapter
{
private Context context;
private int layout;
public MyCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to)
{
super(context, layout, c, from, to);
this.context = context;
this.layout = layout;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
Cursor c = getCursor();
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
CheckBox chkBoxBtn = (CheckBox) v.findViewById (R.id.deleteTwittChkBox);
if (chkBoxBtn != null)
{
chkBoxBtn.setChecked(false);
}
return v;
}
@Override
public void bindView(View v, Context context, Cursor c)
{
--binding view to my textsview in my items
//now it's the importat part:
CheckBox chkBoxBtn = (CheckBox) v.findViewById(R.id.deleteTwittChkBox);
if (chkBoxBtn != null)
{
chkBoxBtn.setId(Integer.valueOf(c.getString(c
.getColumnIndex(MyUsers.User._ID))));
chkBoxBtn.setOnClickListener(new OnItemClickListener(chkBoxBtn, v));
chkBoxBtn.setChecked(false);
}
}
//i couldnt find another way of doing this, but this is how i set listeners to my checkboxses
static ArrayList<String> checkedItemsList = new ArrayList<String>();
private class OnItemClickListener implements OnClickListener
{
private int mPosition;
private CheckBox chkBox;
OnItemClickListener(CheckBox mChkBox, View v)
{
chkBox = mChkBox;
chkBox.setChecked(false);
}
@Override
public void onClick(View v)
{
if (chkBox.isChecked())
{
checkedItemsList.add(String.valueOf(chkBox.getId()));
}
else
{
checkedItemsList.remove(String.valueOf(chkBox.getId()));
}
}
}
}
Вот часть кода из ListActivity
класс, который описывает кнопку, которая удаляет отмеченные элементы:
OnClickListener btListener = new OnClickListener()
{
public void onClick(View view)
{
// long[] items = listView.getCheckItemIds();
int x = 0;
Uri myUri = Uri
.parse("content://com.idan.datastorageprovider/users");
String where = "_id" + "=?";
//here i am tatking all checkboxes which ive added from the adapter class
ArrayList<String> checkedItemsList = MySimpleCursorAdapter.checkedItemsList;
for (String itemID : checkedItemsList)
{
getContentResolver()
.delete(myUri, where, new String[] { itemID});
checkedItemsList.remove(itemID);
}
}
};
Решение
Я сомневаюсь, что SimpleCursorAdapter — подходящий класс для расширения здесь.
Связано ли состояние «проверено» каким-либо образом с XML-данными?Нет?Итак, вам нужен собственный адаптер!
По сути, все адаптеры должны реализовывать способ создания представления из данного элемента (точнее, позиции элемента!).Это будет вызвано в любой момент, когда список захочет отобразить элемент.Теперь трюк, который он использует, заключается в повторном использовании ранее созданных элементов представления списка, которые больше нельзя увидеть на экране!Таким образом:когда вы прокручиваете список вниз и элемент исчезает вверху, ТОЧНО этот объект представления будет повторно использоваться для следующего появляющегося элемента.
Таким образом, когда этот метод вызывается с данным «старым» представлением, которое следует использовать повторно, все содержащиеся в нем элементы должны быть установлены в соответствии с данными элементов.Если флажок является частью этой игры, вам понадобится хранилище для отмеченного состояния!Недостаточно иметь флажок, так как объектов флажка будет меньше, поскольку элементов списка!
SimpleCursorAdapters существуют для того, чтобы — да — представлять ПРОСТЫЕ вещи.XML-файл, описывающий данные (изображения и текст, как указано в документации).Из-за этой простоты все, что вам нужно сделать здесь, это предоставить метод для создания НОВЫХ объектов представления элементов - вы ВООБЩЕ не перехватываете процесс повторного использования!По сути, он знает только, как поместить данные в существующий объект представления, но ему не хватает знаний о том, как обращаться с отмеченными/снятыми флажками!
Ваше решение:напишите собственное расширение BaseAdapter и сделайте то, что нужно:реализовать «getView» (и некоторые другие методы, такие как getItem, getItemId и getCount).Это совсем не сложно!Этот Демо-версия API использует BaseAdapter и mExpanded
состояние здесь в основном идентично состояниям вашего флажка!
Удачи!
Другие советы
Возможно, вам придется позвонить уведомитьDataSetChanged когда вы изменяете данные.
Проблема, вероятно, в том, что вы вызываете setChecked из onItemClickListener.Один из хакерских способов обойти это — сделать следующее до и после вызова setChecked из вашего прослушивателя:
chkBox.setClickable(false);
chkBox.setChecked(false);
checkBox.setClickable(true);
Это предотвратит вызов вашего onItemClickListener при ручном вызове setChecked.