[英]Android How to know which check box is selected
I'm making my first Android application and I'm having a problem for which I can't find the answer anywhere on Google.我正在制作我的第一个 Android 应用程序,但我遇到了一个问题,我在谷歌的任何地方都找不到答案。
I want a list of items with checkboxes.我想要一个带有复选框的项目列表。 I want both the item itself and the checkbox to be clickable.
我希望项目本身和复选框都是可点击的。
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;
}
}
}
Don't worry about the chosen variable.不要担心选择的变量。 I wrote that to simply the code.
我把它写成简单的代码。 It actually corresponds to a value in a database.
它实际上对应于数据库中的一个值。 The clicking on an item works just fine.
单击一个项目就可以了。 However when I click on a checkbox what happens is this:
但是,当我单击复选框时,会发生以下情况:
I would appreciate any help you could provide me.我将不胜感激您能为我提供的任何帮助。 Thanks in advance.
提前致谢。
Actually, the implementation backing chosen
is key.实际上,
chosen
的实施支持是关键。 Android does some optimization with list views to allow you to reuse the list item views to avoid excessive object creation and garbage collection (which would often lead to jerky scrolling). Android 对列表视图进行了一些优化,以允许您重用列表项视图以避免过多的 object 创建和垃圾收集(这通常会导致滚动不顺畅)。 As such, you have to make sure that whenever relevant, you know exactly which list item you're working with.
因此,您必须确保无论何时相关,您都确切知道您正在使用哪个列表项。
Let's say that you have a 100 list items.假设您有 100 个列表项。 Your screen is probably not going to be able to display all of them.
您的屏幕可能无法显示所有这些。 You might only show ten items at a time.
您一次只能显示十个项目。 So 10 views (really view hierarchies) are created to display those visible items.
因此创建了 10 个视图(真正的视图层次结构)来显示这些可见项目。 When you scroll down to the next ten items, instead of creating 10 new views (for a total of 20), the list might only create one more (to cover the case where half of one item is showing at the top and half of one is showing at the bottom of the screen for a total of 11 items visible on the screen) and the rest of items reuse the views created before.
当您向下滚动到接下来的 10 个项目时,而不是创建 10 个新视图(总共 20 个),列表可能只会再创建一个(以涵盖一个项目的一半显示在顶部和一个项目的一半的情况显示在屏幕底部,总共有 11 个项目在屏幕上可见)并且项目的 rest 重用了之前创建的视图。
So a conceptual table representing the first screen might look like this:因此,代表第一个屏幕的概念表可能如下所示:
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
And for after scrolling down ten items, it might look a little like this (probably not exactly, but this gets you the idea):向下滚动十个项目后,它可能看起来有点像这样(可能不完全是,但这让你明白了):
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
So what you can gather from this is that a single given view can represent different items as you scroll around.因此,您可以从中收集到的是,单个给定视图可以在您滚动时表示不同的项目。 This means that your event handlers have to be a little more dynamic in how they find the item they're related to.
这意味着您的事件处理程序必须更加动态地查找与其相关的项目。
All this is to give you a bit of background so that you can change how you're implementing your getView
method.所有这些都是为了给您一些背景知识,以便您可以更改实现
getView
方法的方式。 Here's your actual problem: the variable item
is in the scope of your Adapter
.这是您的实际问题:变量
item
位于Adapter
的 scope 中。 Unfortunately, I'm guessing that your code that you haven't posted here that you've replaced with chosen
uses item
.不幸的是,我猜您没有在此处发布的代码已替换为
chosen
uses item
。 You set item
whenever an item view gets created.每当创建项目视图时,您就设置
item
。 This means that after those first 8 views are created, item
is set to the 8th item in your list.这意味着在创建前 8 个视图之后,
item
将设置为列表中的第 8 个项目。 Whenever you click on a checkbox, you're using item
which is the 8th item and not the item that corresponds to the list item view that you clicked.每当您单击复选框时,您使用的是第 8 个
item
,而不是与您单击的列表项视图相对应的项目。
Here's the structure for getView
that I'd recommend:这是我推荐的
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;
}
}
Note that I've gotten rid of the class-level item
variable.请注意,我已经摆脱了类级别的
item
变量。
Try this尝试这个
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;
}
You should save isChecked value in your MyItem object and explicit set checked to checkbox in getView method of your adapter.您应该将 isChecked 值保存在 MyItem object 中,并在适配器的 getView 方法中将选中的复选框显式设置为复选框。 Use onCheckedChangedListener.
使用 onCheckedChangedListener。
If I am following your explanation it sounds like you have a list and each row in the list has a Checkbox and a TextView.如果我按照你的解释,听起来你有一个列表,列表中的每一行都有一个复选框和一个 TextView。 In my app I have something similar and instead of trying to make both the Checkbox and TextView clickable and react to that I use the ListView's onItemclick.
在我的应用程序中,我有类似的东西,而不是尝试使 Checkbox 和 TextView 都可点击并对此做出反应,我使用 ListView 的 onItemclick。 When you catch the user pressed an item in the list, then in the code you can check or un-check the Checkbox.
当您捕捉到用户按下列表中的某个项目时,您可以在代码中选中或取消选中复选框。 It gives the visual impression that the user is able to check the box, but is super easy to implement.
它给人的视觉印象是用户可以选中该框,但非常容易实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.