Java Android listActivity onListItemClick with复选框

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

我的问题是如何访问和更改listactivity中任何项目的复选框模式。我有一个带有复选框和文本视图的XML模板文件,它们定义了一行。以下是我目前正在尝试的:

@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); 
    }
 }