带有CheckBox的Android listActivity onListItemClick

时间:2011-06-26 15:47:20

标签: java android xml checkbox listactivity

我的问题是如何访问和更改listactivity中任何项目的复选框模式。我有一个带有复选框和textview的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只切换第一个复选框(实际上,它会执行我在屏幕上看到的列表中任何部分的第一个复选框)。我不知道用什么函数来获取任何行的复选框。 Toast工作正常,所以至少它能正确记录位置。

感谢您的帮助。

编辑 - 我现在正在尝试将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; 
}

}

作为参考,这里是我正在制作的ListActivity的XML:

<?xml version="1.0" encoding="utf-8"?>

 <ListView android:id="@android:id/list"
           android:layout_width="fill_parent"
           android:layout_height="fill_parent"
           android:layout_weight="1"
           android:drawSelectorOnTop="false"
           android:fastScrollEnabled="true"
           android:cacheColorHint="#00000000"
           />

 <TextView android:id="@android:id/empty"
           android:layout_width="fill_parent"
           android:layout_height="fill_parent"
           android:text="No data"/>

当前行为:SD卡中的歌曲列表被制作成一个不错的可滚动列表。我从getView()的onClick得到了一些正确的响应:第一次点击一个项目,它的标签是“1”并且它的背景变成白色,而第二次我为同一个项目敬酒,我得到“ 0“,背景变黑,这是预期的。

问题是如果我选择item1(使其背景为白色)然后向下滚动,我会注意到item11,item21,item31,...等也有白色背景。但是当我点击它们时,它们的ID属性变为“1”,这意味着它们在技术上从未被点击过!所以基本上当滚动“刷新”到下一个10的列表时,它会复制前10个的颜色方案......?

希望我能清楚地解释清楚。

3 个答案:

答案 0 :(得分:3)

我认为这是一个更深层次的问题,不需要直接回答。

你想要达到什么目的?你真的想要选择你在屏幕上看到的复选框吗?请注意,这可能非常随机 - 列表视图仅保存屏幕上可见的复选框的项目视图,并且只要项目在屏幕外滚动,它们就会重复用于其他项目。

我会说几乎可以肯定你需要更改列表中所有复选框的状态(即使那些不可见的)或它们的某些子集(如部分)。这真正转化为应该采取的正确方式:

  • 适当修改您的数据模型 标记在相应数据模型元素中选择的适当标志 (您为每个项目存储的一些布尔值)
  • 在适配器上调用notifyDataSetChanged()。

因此,列表视图将重新创建屏幕上可见的所有视图。假设适配器中的“getView()”正确写入,它将读取正确的模型并适当更新项目上的已检查状态。 通过notifyDataSetChanged - 如果屏幕上有10个项目可见,那么每个可见项目都会调用10次getView()。

答案 1 :(得分:1)

我建议使用android:choiceMode="multipleChoice"而不是以这种方式手动操作行。行小部件需要实现Checkable接口,可以使用CheckedTextView作为行本身,或creating a subclass of your desired container and implementing Checkable on it来完成。

答案 2 :(得分:0)

您使用“全局”视图而不是行视图。试试这样:

 @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); 
    }
 }
相关问题