Android保存checkbox状态在ListView与光标适配器

我不能find一种方法来保存使用光标适配器时的checkbox状态。 一切工作正常,但如果我点击一个checkbox,它被重复时,它被回收。 我见过使用arrays适配器的例子,但由于我缺乏经验,我发现很难将其翻译成使用游标适配器。 有人能给我一个如何去做的例子。 任何帮助赞赏。

private class PostImageAdapter extends CursorAdapter { private static final int s = 0; private int layout; Bitmap bm=null; private String PostNumber; TourDbAdapter mDbHelper; public PostImageAdapter (Context context, int layout, Cursor c, String[] from, int[] to, String Postid) { super(context, c); this.layout = layout; PostNumber = Postid; mDbHelper = new TourDbAdapter(context); mDbHelper.open(); } @Override public View newView(Context context, final Cursor c, ViewGroup parent) { ViewHolder holder; LayoutInflater inflater=getLayoutInflater(); View row=inflater.inflate(R.layout.image_post_row, null); holder = new ViewHolder(); holder.Description = (TextView) row.findViewById(R.id.item_desc); holder.cb = (CheckBox) row.findViewById(R.id.item_checkbox); holder.DateTaken = (TextView) row.findViewById(R.id.item_date_taken); holder.Photo = (ImageView) row.findViewById(R.id.item_thumb); row.setTag(holder); int DateCol = c.getColumnIndex(TourDbAdapter.KEY_DATE); String Date = c.getString(DateCol); int DescCol = c.getColumnIndex(TourDbAdapter.KEY_CAPTION); String Description = c.getString(DescCol); int FileNameCol = c.getColumnIndex(TourDbAdapter.KEY_FILENAME); final String FileName = c.getString(FileNameCol); int PostRowCol = c.getColumnIndex(TourDbAdapter.KEY_Post_ID); String RowID = c.getString(PostRowCol); String Path = "sdcard/Tourabout/Thumbs/" + FileName + ".jpg"; Bitmap bm = BitmapFactory.decodeFile(Path, null); holder.Photo.setImageBitmap(bm); holder.DateTaken.setText(Date); holder.Description.setText(Description); holder.cb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { CheckBox cBox = (CheckBox) v; if (cBox.isChecked()) { mDbHelper.UpdatePostImage(FileName, PostNumber); } else if (!cBox.isChecked()) { mDbHelper.UpdatePostImage(FileName, ""); } } }); return row; }; @Override public void bindView(View row, Context context, final Cursor c) { ViewHolder holder; holder = (ViewHolder) row.getTag(); int DateCol = c.getColumnIndex(TourDbAdapter.KEY_DATE); String Date = c.getString(DateCol); int DescCol = c.getColumnIndex(TourDbAdapter.KEY_CAPTION); String Description = c.getString(DescCol); int FileNameCol = c.getColumnIndex(TourDbAdapter.KEY_FILENAME); final String FileName = c.getString(FileNameCol); int PostRowCol = c.getColumnIndex(TourDbAdapter.KEY_Post_ID); String RowID = c.getString(PostRowCol); String Path = "sdcard/Tourabout/Thumbs/" + FileName + ".jpg"; Bitmap bm = BitmapFactory.decodeFile(Path, null); File x = null; holder.Photo.setImageBitmap(bm); holder.DateTaken.setText(Date); holder.Description.setText(Description); holder.cb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { CheckBox cBox = (CheckBox) v; if (cBox.isChecked()) { mDbHelper.UpdatePostImage(FileName, PostNumber); } else if (!cBox.isChecked()) { mDbHelper.UpdatePostImage(FileName, ""); } } }); } } static class ViewHolder{ TextView Description; ImageView Photo; CheckBox cb; TextView DateTaken; } } 

我build议你使用Android的内置支持多选列表( CHOICE_MODE_MULTIPLE )。

List11.java SDK示例演示了这一点。 您也可以从我的教程中find一个项目, 在这里使用它。

只要你在android.R.layout.simple_list_item_multiple_choice资源中包含一个带有android:id="@android:id/text1"CheckedTextView ,你仍然可以使用这种技术。您的SDK。

另外,看到这个问题和这个问题以及这个问题和这个问题 。

我自己也有同样的问题:如何切换多个selectCheckedTextView自定义布局(即不使用android.R.layout.simple_list_item_multiple_choice

以下为我工作。 我的例子是一个自定义的视图,它提供了一个从SimpleCursorAdapter扩展的适配器

我的自定义视图(row_contact.xml):

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="fill_parent"> <CheckedTextView android:id="@android:id/text1" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:textAppearance="?android:attr/textAppearanceLarge" android:gravity="center_vertical" android:paddingLeft="6dip" android:paddingRight="6dip" android:checkMark="?android:attr/listChoiceIndicatorMultiple" /> <TextView android:text="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tvNumber" android:layout_gravity="bottom" android:paddingLeft="6dip" android:paddingRight="6dip" /> </FrameLayout> 

适配器在ListActivity.OnCreate中创build,它调用setupViews():

  private void setupViews() { bOk = (Button) findViewById(R.id.ButtonOK); bCancel = (Button) findViewById(R.id.ButtonCancel); FListView = getListView(); // bOk.setText("Select"); // FListView.setItemsCanFocus(false); FListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); // bOk.setOnClickListener(this); bCancel.setOnClickListener(this); // ContentResolver content = getContentResolver(); Cursor cursor = ApplicationHelper.MobilePhoneContacts(content); startManagingCursor(cursor); ListAdapter adapter = new CheckedCursorAdapter( SelectContacts.this, R.layout.row_contact, cursor, new String[] {People.NAME, People.NUMBER}, new int[] {android.R.id.text1, R.id.tvNumber}); setListAdapter(adapter); } 

自定义适配器:

  public class CheckedCursorAdapter extends SimpleCursorAdapter { Activity context; Cursor c; public CheckedCursorAdapter(Activity context, int rowContact, Cursor cursor, String[] strings, int[] is) { super(context, rowContact, cursor, strings, is); this.context = context; this.c = cursor; } public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; ContactRowWrapper wrapper; if (row == null) { LayoutInflater inflater=context.getLayoutInflater(); row = inflater.inflate(R.layout.row_contact, null); // wrapper = new ContactRowWrapper(row); row.setTag(wrapper); } else { wrapper = (ContactRowWrapper)row.getTag(); } c.moveToPosition(position); wrapper.getTextView().setText( c.getString(c.getColumnIndex(Contacts.People.NUMBER)) ); wrapper.getcheckBox().setText( c.getString(c.getColumnIndex(Contacts.People.NAME)) ); wrapper.getcheckBox().setChecked(getListView().isItemChecked(position)); // return row; } } 

对于我来说代码的关键是获取checkbox的工作是:

 wrapper.getcheckBox().setChecked(getListView().isItemChecked(position)); 

希望这可以帮助你或任何其他人绊倒这个问题。

另外,请原谅我的Java noobness …我几个星期前才开始Java。

在getView方法上声明CheckBox并使用这个代码

 CheckBox checkBtn =(CheckBox) convertView.findViewById(R.id.phCheckBox); checkBtn.setChecked(Boolean.parseBoolean((vList.get(position).getCheckBtnStatus()))); checkBtn.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { if(checkBtn.isChecked()==true) { vList.get(position).setCheckBtnStatus("true"); System.out.println("vList.get(position)---"+vList.get(position).getCheckBtnStatus()+" -"+position); } else { vList.get(position).setCheckBtnStatus("false"); System.out.println("else vList.get(position)---"+vList.get(position).getCheckBtnStatus()+"-"+position); } } }); 

之后,在主要的活动你必须检查哪个位置的checkbox是真实的

 save.setOnClickListener(new OnClickListener() { public void onClick(View v) { for (int i = 0; i < newList.size(); i++) { UserData v1 = newList.get(i); status = Boolean.parseBoolean(v1.getCheckBtnStatus()); if (status == true) { //write ur code here } }}); 
 3. Code Code Attach listeners inside your activity “onCreate()” method, to monitor following events : If checkbox id : “chkIos” is checked, display a floating box with message “Bro, try Android”. If button is is clicked, display a floating box and display the checkbox states. File : MyAndroidAppActivity.java package com.mkyong.android; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.Toast; public class MyAndroidAppActivity extends Activity { private CheckBox chkIos, chkAndroid, chkWindows; private Button btnDisplay; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); addListenerOnChkIos(); addListenerOnButton(); } public void addListenerOnChkIos() { chkIos = (CheckBox) findViewById(R.id.chkIos); chkIos.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //is chkIos checked? if (((CheckBox) v).isChecked()) { Toast.makeText(MyAndroidAppActivity.this, "Bro, try Android :)", Toast.LENGTH_LONG).show(); } } }); } public void addListenerOnButton() { chkIos = (CheckBox) findViewById(R.id.chkIos); chkAndroid = (CheckBox) findViewById(R.id.chkAndroid); chkWindows = (CheckBox) findViewById(R.id.chkWindows); btnDisplay = (Button) findViewById(R.id.btnDisplay); btnDisplay.setOnClickListener(new OnClickListener() { //Run when button is clicked @Override public void onClick(View v) { StringBuffer result = new StringBuffer(); result.append("IPhone check : ").append(chkIos.isChecked()); result.append("\nAndroid check : ").append(chkAndroid.isChecked()); result.append("\nWindows Mobile check :").append(chkWindows.isChecked()); Toast.makeText(MyAndroidAppActivity.this, result.toString(), Toast.LENGTH_LONG).show(); } }); } } 
  1. CheckBox打开“res / layout / main.xml”文件,在LinearLayout中添加3个“CheckBox”和一个button。

文件:res / layout / main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <CheckBox android:id="@+id/chkIos" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/chk_ios" /> <CheckBox android:id="@+id/chkAndroid" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/chk_android" android:checked="true" /> <CheckBox android:id="@+id/chkWindows" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/chk_windows" /> <Button android:id="@+id/btnDisplay" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_display" /> </LinearLayout>