简体   繁体   English

Android使用光标适配器保存ListView中的复选框状态

[英]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();

      }
    });

  }
}
  1. CheckBox Open “res/layout/main.xml” file, add 3 “CheckBox” and a button, inside the LinearLayout. CheckBox打开“res / layout / main.xml”文件,在LinearLayout中添加3个“CheckBox”和一个按钮。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM