Android listActivity onListItemClick with CheckBox

依然范特西╮ 提交于 2020-01-05 08:56:13

问题


my question is how to access and change the checkBox mode for any item in a listactivity. I have an XML template file with a checkbox and a textview, and these define a row. Here's what I'm trying so far:

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

}

Obviously though using R.id.checkbox only toggles the first checkbox (actually, it does the first checkbox of whatever part of the list I'm looking at on my screen). I'm not sure what function to use to get the checkbox of any row though. The Toast works fine btw, so at least it registers position properly.

Thanks for any help.

EDIT - I'm now trying to subclass the SimpleCursorAdapter to better control the behaviour I want. Here is that subclass:

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

}

And for reference, here is the XML of the ListActivity I'm making:

<?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"/>

Current behaviour: the list of songs from the SD card is made into a nice scrollable list. I do get somewhat proper responses from getView()'s onClick: The first time I click an item, it Toasts that its tag is "1" and its background goes white, while the second time I toast the same item, I get "0" and the background goes black, which is as expected.

The problem is if I select item1 (making its background white) and then scroll down, I'll notice that item11, item21, item31, ... , etc ALSO have white backgrounds. But when I click on them, their ID attribute goes to "1", meaning they've technically never been clicked before! So basically when the scroll "refreshes" to the next list of 10, it copies the color scheme of the first 10...?

Hope I explained it clearly.


回答1:


I think this is bit deeper question and not direct answer is needed.

What do you want to achieve? Do you really want to make selected ONLY the checkboxes that you see on screen? Mind that this might be pretty random - list view only holds item views for the checkboxes that are visible on screen and they are reused for other items whenever the item is scrolled outside the screen.

I'd say that almost for sure you need to change state of all the checkboxes in your list (even those not visible) or some subset of them (like section). Which really translates into the proper way it should be done:

  • modify your data model appropriately marking the appropriate flags selected in corresponding data model elements (some boolean values you store per item)
  • call notifyDataSetChanged() on your adapter.

As a result, list view will recreate all the views which are visible on screen. Assuming that your "getView()" in adapter is written correctly, it will read the right model and update checked state on the item appropriately. By notifyDataSetChanged - if you have 10 items visible on screen you will have 10 times getView() called for every item visible.




回答2:


I recommend using android:choiceMode="multipleChoice" instead of manually manipulating your rows this way. The row widget will need to implement the Checkable interface, which can either be done by using CheckedTextView as the row itself, or creating a subclass of your desired container and implementing Checkable on it.




回答3:


You use "global" view instead your row view. Try like that:

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


来源:https://stackoverflow.com/questions/6484964/android-listactivity-onlistitemclick-with-checkbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!