флажок в списке проверяется неожиданно - PullRequest
0 голосов
/ 16 февраля 2010

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

Ответы [ 3 ]

2 голосов
/ 16 февраля 2010

Я сомневаюсь, что SimpleCursorAdapter - подходящий класс для расширения здесь.

Связано ли "проверенное" состояние с данными XML каким-либо образом? Нет? Так что вам нужен собственный адаптер!

В основном все адаптеры должны реализовывать способ генерирования представления из заданного элемента (точнее, позиции элемента!). Это будет вызвано в любое время, когда список хочет отобразить элемент. Теперь уловка, которую он использует, состоит в том, чтобы повторно использовать ранее созданные элементы представления списка, которые больше не видны на экране! Таким образом: когда вы прокручиваете свой список вниз и элемент исчезает сверху, ИМЕННО этот объект просмотра будет повторно использован для следующего появившегося элемента.

Таким образом, когда этот метод вызывается с заданным «старым» представлением, которое следует использовать повторно, все содержащиеся в нем элементы должны быть установлены в соответствии с данными элементов. Если флажок является частью этой игры, у вас должно быть хранилище для проверенного состояния! Недостаточно иметь флажок, так как объектов флажка будет меньше, поскольку есть элементы списка!

SimpleCursor Адаптеры предназначены для - да - представления ПРОСТЫХ вещей. XML, описывающий данные (изображения и текст, как указано в документации). Из-за этой простоты все, что вам нужно здесь сделать, - это предоставить метод для создания НОВЫХ объектов представления элементов - вы не перехватываете процесс повторного использования ВСЕ! Он в основном знает только, как поместить данные в существующий объект представления, но ему не хватает знаний о том, как обрабатывать отмеченные / не отмеченные поля!

Ваше решение: написать свое собственное расширение BaseAdapter и сделать то, что должно быть сделано: реализовать "getView" (и некоторые другие методы, такие как getItem, getItemId и getCount). Это совсем не сложно! Это API Demo использует BaseAdapter, и состояние mExpanded здесь в основном идентично вашим состояниям флажков!

Удачи!

0 голосов
/ 16 февраля 2010

Возможно, проблема в том, что вы вызываете setChecked из onItemClickListener. Один хакерский способ обойти это - сделать следующее до и после вызова setChecked из слушателя:

chkBox.setClickable(false);
chkBox.setChecked(false);
checkBox.setClickable(true);

Это предотвратит вызов вашего onItemClickListener при ручном вызове setChecked.

0 голосов
/ 16 февраля 2010

Возможно, вам потребуется вызвать notifyDataSetChanged при изменении данных.

...