[英]Android save Checkbox State in ListView with Cursor Adapter
I cant find a way to save the checkbox state when using a Cursor adapter. 使用光标适配器时,我无法找到保存复选框状态的方法。 Everything else works fine but if i click on a checkbox it is repeated when it is recycled. 其他一切工作正常,但如果我点击一个复选框,它会被重复使用。 Ive seen examples using array adapters but because of my lack of experience im finding it hard to translate it into using a cursor adapter. 我见过使用数组适配器的例子,但由于我缺乏经验,我发现很难将其转换为使用游标适配器。 Could someone give me an example of how to go about it. 有人能给我一个如何去做的例子。 Any help appreciated. 任何帮助赞赏。
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;
}
}
I had the same issue myself: how to toggle multiple select CheckedTextView in a custom layout (ie not using android.R.layout.simple_list_item_multiple_choice ) 我自己也有同样的问题:如何在自定义布局中切换多个选择CheckedTextView(即不使用android.R.layout.simple_list_item_multiple_choice )
The following worked for me. 以下对我有用。 The example I have is a custom view that is provided an adaptor extended from SimpleCursorAdapter. 我的示例是一个自定义视图,提供从SimpleCursorAdapter扩展的适配器。
My custom view (row_contact.xml): 我的自定义视图(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>
The adaptor is created in ListActivity.OnCreate, which calls setupViews(): 适配器是在ListActivity.OnCreate中创建的,它调用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);
}
The Custom adaptor: 自定义适配器:
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;
}
}
The crucial bit of code for for me was to get check boxes working was: 对我而言,关键的代码是让复选框正常工作:
wrapper.getcheckBox().setChecked(getListView().isItemChecked(position));
Hope this helps you or anyone else who stumbles onto this question. 希望这可以帮助你或其他任何偶然发现这个问题的人。
Also, pardon my Java noobness... I've only started Java a few weeks ago. 另外,原谅我的Java noobness ......我几周前才开始使用Java。
I would recommend you use Android's built-in support for multiple-choice lists ( CHOICE_MODE_MULTIPLE
). 我建议你使用Android内置的多选列表支持( CHOICE_MODE_MULTIPLE
)。
The List11.java
SDK sample demonstrates this. List11.java
SDK示例演示了这一点。 You can also find a project from one of my tutorials that uses it here . 您也可以找到我的教程的一个使用它的一个项目在这里 。
You can still use this technique with your own layout, so long as you include a CheckedTextView
with android:id="@android:id/text1"
as shown in the android.R.layout.simple_list_item_multiple_choice
resource, a copy of which ships with your SDK. 你仍然可以在你自己的布局中使用这种技术,只要你在android.R.layout.simple_list_item_multiple_choice
资源中包含一个带有android:id="@android:id/text1"
的CheckedTextView
,其副本随附你的SDK。
Also, see this question and this question and this question and this question . 另外,请看这个问题和这个问题以及这个问题和这个问题 。
Declare the CheckBox on getView Method and use this code 在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);
}
}
});
After that on the main Activity u have to check which position of checkbox is true 在主Activity之后你必须检查复选框的哪个位置为真
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();
}
});
}
}
File : res/layout/main.xml 文件: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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.