我正在制作我的第一个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;
}
}
}
不要担心所选变量。我写的只是代码。它实际上对应于数据库中的值。点击一个项目就可以了。但是当我点击一个复选框时会发生什么:
感谢您提供给我的任何帮助。提前谢谢。
答案 0 :(得分: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;
}
}
请注意,我已经摆脱了班级item
变量。
答案 1 :(得分:2)
试试这个
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;
}
答案 2 :(得分:0)
您应该在MyItem对象中保存isChecked值,并在适配器的getView方法中将显式设置选中复选框。使用onCheckedChangedListener。
答案 3 :(得分:0)
如果我按照你的说明理解你有一个列表,列表中的每一行都有一个Checkbox和一个TextView。在我的应用程序中,我有类似的东西,而不是试图使Checkbox和TextView可单击并对其做出反应,我使用ListView的onItemclick。当您抓住用户按下列表中的项目时,您可以在代码中选中或取消选中复选框。它给人的视觉印象是用户可以选中复选框,但非常容易实现。