Android如何知道选中了哪个复选框

Inê*_*nês 7 checkbox android list listactivity android-arrayadapter

我正在制作我的第一个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;
        }
    }    
}
Run Code Online (Sandbox Code Playgroud)

不要担心所选变量.我写的只是代码.它实际上对应于数据库中的值.点击一个项目就可以了.但是,当我点击一个复选框时,会发生什么:

  • 我单击的复选框显示为选中状态(这是Android UI的工作)
  • 内部检查的复选框是屏幕上的最后一个,无论它是什么,即,如果我的屏幕显示8个项目,我点击其中一个(无关紧要哪个),检查出现在正确的复选框中,但内部,第8项是获得检查的项目.

我很感激你能提供给我的任何帮助.提前致谢.

kab*_*uko 6

实际上,实施支持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将设置为列表中的第8个项目.每当您单击复选框时,您正在使用item哪个是第8个项目,而不是与您单击的列表项视图对应的项目.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已经摆脱了类级item变量.