Java Android listActivity onListItemClick with复选框
我的问题是如何访问和更改listactivity中任何项目的复选框模式。我有一个带有复选框和文本视图的XML模板文件,它们定义了一行。以下是我目前正在尝试的:Java Android listActivity onListItemClick with复选框,java,android,xml,checkbox,listactivity,Java,Android,Xml,Checkbox,Listactivity,我的问题是如何访问和更改listactivity中任何项目的复选框模式。我有一个带有复选框和文本视图的XML模板文件,它们定义了一行。以下是我目前正在尝试的: @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); Toast.makeText(this, "You sel
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Toast.makeText(this, "You selected: " + Integer.toString(position), Toast.LENGTH_LONG).show();
CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox);
if (checkbox.isChecked() == false) {
checkbox.setChecked(true);
} else {
checkbox.setChecked(false);
}
}
显然,尽管使用R.id.checkbox只会切换第一个复选框(实际上,它会切换我在屏幕上看到的列表的任何部分的第一个复选框)。我不确定使用什么函数来获取任何行的复选框。顺便说一句,吐司很好用,所以至少它正确地记录了位置
谢谢你的帮助
编辑-我现在尝试将SimpleCursorAdapter子类化,以便更好地控制我想要的行为。下面是该子类:
public class musicPlaylist extends SimpleCursorAdapter {
private Cursor c;
private Context context;
private ArrayList<String> checkList = new ArrayList<String>();
private final static int SELECTED = 1;
private final static int NOT_SELECTED = 0;
public musicPlaylist(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.song_item, null);
}
this.c.moveToPosition(pos);
int columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
String song = this.c.getString(columnIndex);
TextView sTitle = (TextView) v.findViewById(R.id.text1);
sTitle.setText(song);
v.setId(NOT_SELECTED);
v.setTag(song);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.getId() == NOT_SELECTED) {
v.setId(SELECTED);
Toast.makeText(context, "Test: " + v.getId(), Toast.LENGTH_SHORT).show();
v.setBackgroundColor(Color.parseColor("#FFFFFF"));
} else {
v.setId(NOT_SELECTED);
Toast.makeText(context, "Test: " + v.getId(), Toast.LENGTH_SHORT).show();
v.setBackgroundColor(Color.parseColor("#000000"));
}
}
});
return v;
}
public类musicPlaylist扩展了SimpleCursorAdapter{
专用游标c;
私人语境;
私有ArrayList检查表=新建ArrayList();
选择的专用最终静态int=1;
未选择私有最终静态整数=0;
公共音乐播放列表(上下文、int布局、光标c、,
字符串[]从,整数[]到){
super(上下文、布局、c、from、to);
这个.c=c;
this.context=上下文;
}
公共视图getView(int pos、View inView、ViewGroup父视图){
视图v=查看;
如果(v==null){
LayoutFlater充气器=(LayoutFlater)context.getSystemService(context.LAYOUT\u充气器\u服务);
v=充气机充气(R.layout.song_项,空);
}
此.c.移动位置(pos);
int columnIndex=this.c.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
String song=this.c.getString(columnIndex);
TextView-sTitle=(TextView)v.findViewById(R.id.text1);
塞特尔特(歌曲);
v、 setId(未选择);
v、 setTag(歌曲);
v、 setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//TODO自动生成的方法存根
如果(v.getId()==未选中){
v、 setId(选定);
Toast.makeText(上下文,“Test:+v.getId(),Toast.LENGTH_SHORT).show();
v、 setBackgroundColor(Color.parseColor(#FFFFFF”);
}否则{
v、 setId(未选择);
Toast.makeText(上下文,“Test:+v.getId(),Toast.LENGTH_SHORT).show();
v、 setBackgroundColor(Color.parseColor(#000000”);
}
}
});
返回v;
}
}
作为参考,下面是我正在制作的ListActivity的XML:
<?xml version="1.0" encoding="utf-8"?>
当前行为:SD卡中的歌曲列表被制作成一个漂亮的可滚动列表。我确实从getView()的onClick中得到了一些正确的响应:第一次单击某个项目时,它会祝酒,表示其标记为“1”,背景为白色,而第二次单击同一项目时,我得到了“0”,背景为黑色,这与预期的一样
问题是如果我选择item1(使其背景为白色),然后向下滚动,我会注意到item11、item21、item31,等也有白色背景。但当我点击它们时,它们的ID属性变为“1”,这意味着它们在技术上从未被点击过!所以基本上当卷轴“刷新”到下一个10个列表时,它会复制前10个的配色方案
希望我解释清楚。我建议使用android:choiceMode=“multipleechoice”而不是以这种方式手动操作行。行窗口小部件需要实现可检查的
界面,该界面可以使用CheckedTextView
作为行本身,也可以使用“全局”视图代替行视图。试一试:
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
CheckBox checkbox = (CheckBox) v.findViewById(R.id.checkbox);
if (checkbox.isChecked() == false) {
checkbox.setChecked(true);
} else {
checkbox.setChecked(false);
}
}
我认为这是一个更深层次的问题,不需要直接回答
你想要实现什么?是否确实要仅选中屏幕上显示的复选框?请注意,这可能是非常随机的-列表视图只保存屏幕上可见的复选框的项目视图,并且每当项目滚动到屏幕外时,这些复选框将被重新用于其他项目
我想说,几乎可以肯定的是,您需要更改列表中所有复选框的状态(即使是那些不可见的复选框)或它们的某个子集(如第节)。这实际上转化为正确的方式:
- 适当地修改您的数据模型
标记在相应数据模型元素中选择的适当标志
(每个项目存储的一些布尔值)
- 在适配器上调用notifyDataSetChanged()
因此,“列表视图”将重新创建屏幕上可见的所有视图。假设适配器中的“getView()”编写正确,它将读取正确的模型并适当地更新该项的选中状态。
通过notifyDataSetChanged-如果屏幕上有10个可见项,则每个可见项将调用10次getView() 我想你是对的。到目前为止,我所做的是创建一个新类,它是SimpleCursorAdapter的子类,我正在覆盖getView()方法。一切正常,但我通过更改文本背景色测试了onClick的视图,我得到了“循环”效果或它的调用,如果我在屏幕上选择item1,它假设我也选择了item1、item21等(并更改了所有背景色)。如何使onClick在每个视图中都是唯一的?啊。。这是另一个问题。请看这篇文章-它详细地解释了它:。如果你使用的是自定义背景,那么就只需要使用cacheColorHint(或者禁用Android listView中实现的优化)。嗯,我不认为这是我的问题,因为我做了cacheColorHint,我仍然会遇到item1的onClick应用于item11、item21等的回收问题(基本上是每当屏幕刷新到新的选项集时)。回答的最后一句提到notifyDataSetChanged-我应该在什么地方实现它吗?如何实现?更改所有元素的背景也可能
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
CheckBox checkbox = (CheckBox) v.findViewById(R.id.checkbox);
if (checkbox.isChecked() == false) {
checkbox.setChecked(true);
} else {
checkbox.setChecked(false);
}
}