Android Как узнать, какой флажок установлен - PullRequest
7 голосов
/ 15 августа 2011

Я делаю свое первое приложение для Android, и у меня возникла проблема, из-за которой я нигде не могу найти ответ в Google.

Я хочу список элементов с флажками. Я хочу, чтобы и сам элемент, и флажок были активными.

    public class MyItem extends ListActivity {
        private ArrayList<MyItem> items;
        public void onCreate(Bundle savedInstanceState) {
            /* code which creates instances of MyItem and inserts them on the *list* variable */
        MyArrayAdapter adapter = new MyArrayAdapter(this, R.layout.my_item, list);

        setListAdapater(adapter);
        setContentView(R.layout.items_list);
    }
        public onListItemClick(ListView l, View v, int position, long id){
            //handles the click on an item
        }

    public class MyArrayAdapter extends ArrayAdapter<MyItem>{
        private MyItem item;
        public MyArrayAdapter(Context context, int resourceId, ArrayList<MyItem> list){
            //code for the constructor
        }
        public getView(int position, View convertView, ViewGroup parent){
            convertView = inflater.inflate(resourceId, null);


            this.item = list.get(position);
            if (this.item == null) {
                return convertView;
            }
            else{
                if (resourceId == R.layout.my_item) {
                    final CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox);

                    if(cb != null){
                        //initially
                        if(chosen)
                            cb.setChecked(true);
                        else
                            cb.setChecked(false);
                        //set listener
                        cb.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View arg0) {
                                if(cb.isChecked())
                                    chosen = true;
                                else
                                    chosen = false;
                            }
                        });
                    }
                }
            return convertView;
        }
    }    
}

Не беспокойтесь о выбранной переменной. Я написал это просто для кода. Это на самом деле соответствует значению в базе данных. Нажатие на элемент работает просто отлично. Однако, когда я нажимаю на флажок, происходит следующее:

  • флажок, в котором я нажал, кажется выбранным (это работа пользовательского интерфейса Android)
  • флажок, который установлен внутри, является последним на экране, какой бы он ни был, т.е. если на моем экране отображается 8 элементов, и я нажимаю на один из них (независимо от того, какой из них), проверка отображается в правильном флажок, но внутри, восьмой пункт проверяется.

Буду признателен за любую помощь, которую вы мне сможете оказать. Заранее спасибо.

Ответы [ 4 ]

6 голосов
/ 15 августа 2011

На самом деле поддержка реализации chosen является ключевой.Android выполняет некоторую оптимизацию с представлениями списков, чтобы позволить вам повторно использовать представления элементов списка, чтобы избежать чрезмерного создания объектов и сбора мусора (что часто приводит к прерывистой прокрутке).Таким образом, вы должны убедиться, что, когда это уместно, вы точно знаете, с каким элементом списка вы работаете.

Допустим, у вас есть 100 элементов списка.Ваш экран, вероятно, не сможет отображать все из них.Вы можете показывать только десять предметов одновременно.Таким образом, для отображения этих видимых элементов создано 10 представлений (действительно представлений иерархий).Когда вы прокрутите вниз до следующих десяти элементов, вместо создания 10 новых представлений (всего 20), в списке может появиться только еще одно (для покрытия случая, когда половина одного элемента отображается сверху, а половина - одного элемента).в нижней части экрана отображается в общей сложности 11 элементов, видимых на экране), а остальные элементы повторно используют созданные ранее представления.

Таким образом, концептуальная таблица, представляющая первый экран, может выглядеть следующим образом:

Item     View
-------  --------
Item 1   View 1
Item 2   View 2
Item 3   View 3
Item 4   View 4
Item 5   View 5
Item 6   View 6
Item 7   View 7
Item 8   View 8
Item 9   View 9
Item 10  View 10

И после прокрутки десяти пунктов это может выглядеть примерно так (возможно, не совсем, но это дает вам представление):

Item     View
-------  --------
Item 11  View 1
Item 12  View 2
Item 13  View 3
Item 14  View 4
Item 15  View 5
Item 16  View 6
Item 17  View 7
Item 18  View 8
Item 19  View 9
Item 20  View 10

Итак, что вы можете собратьОтсюда следует, что один данный вид может представлять различные элементы при прокрутке.Это означает, что ваши обработчики событий должны быть немного более динамичными в том, как они находят элемент, с которым они связаны.

Все это для того, чтобы дать вам немного фона, чтобы вы могли изменить то, как выреализовать ваш getView метод.Вот ваша настоящая проблема: переменная item находится в области действия вашей Adapter.К сожалению, я предполагаю, что ваш код, который вы не разместили здесь и который вы заменили на chosen, использует item.Вы устанавливаете item всякий раз, когда создается представление элемента.Это означает, что после того, как эти первые 8 видов созданы, item устанавливается на восьмой элемент в вашем списке.Каждый раз, когда вы нажимаете на флажок, вы используете item, который является восьмым элементом, а не элементом, который соответствует представлению элемента списка, которое вы щелкнули.

Вот структура для getView, которую я бы порекомендовал:

public getView(int position, View convertView, ViewGroup parent){
        View view = convertView;
        if (view == null) {
            view = inflater.inflate(R.layout.my_item, null);
        }

        final MyItem item = list.get(position);
        final CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox);
        // This stores a reference to the actual item in the checkbox
        cb.setTag(item);

        if(item.chosen)
            cb.setChecked(true);
        else
            cb.setChecked(false);

        //set listener
        cb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // This gets the correct item to work with.
                final MyItem clickedItem = (MyItem) view.getTag();
                if(cb.isChecked())
                    clickedItem.chosen = true;
                else
                    clickedItem.chosen = false;
            }
        });

        return view;
    }
}

Обратите внимание, что я избавился от переменной item уровня класса.

2 голосов
/ 16 августа 2011

Попробуйте это

public getView(int position, View convertView, ViewGroup parent){
    View view = convertView;
    if (view == null) {
        view = inflater.inflate(R.layout.my_item, null);
    }

    final MyItem item = list.get(position);
    // This stores a reference to the actual item in the view
    view.setTag(item);

    final CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox);

    //set listener
    cb.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // This gets the correct item to work with.
            final MyItem clickedItem = (MyItem) view.getTag();
            if(cb.isChecked())
                clickedItem.chosen = true;
            else
                clickedItem.chosen = false;
        }
    });


    cb.setChecked(item.chosen);
    return view;
}
0 голосов
/ 15 августа 2011

Если я следую вашему объяснению, похоже, у вас есть список, и у каждой строки в списке есть флажок и TextView.В моем приложении у меня есть что-то похожее, и вместо того, чтобы сделать флажки и TextView кликабельными и реагировать на это, я использую onItemclick в ListView.Когда вы поймали пользователя нажал элемент в списке, то в коде вы можете установить или снять флажок.Это создает визуальное впечатление, что пользователь может установить флажок, но его очень легко реализовать.

0 голосов
/ 15 августа 2011

Вы должны сохранить значение isChecked в вашем объекте MyItem и установить явный флажок в методе getView вашего адаптера. Используйте onCheckedChangedListener.

...