Вопрос

У меня есть список флажков в списке, привязанном 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top