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

时间:2010-03-09 05:48:32

标签: android listview checkbox state

使用光标适配器时,我无法找到保存复选框状态的方法。其他一切工作正常,但如果我点击一个复选框,它会被重复使用。我见过使用数组适配器的例子,但由于我缺乏经验,我发现很难将其转换为使用游标适配器。有人能给我一个如何去做的例子。任何帮助赞赏。

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

5 个答案:

答案 0 :(得分:4)

我自己也有同样的问题:如何在自定义布局中切换多个选择CheckedTextView(即不使用 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中创建的,它调用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;
    }

  }

对我而言,关键的代码是让复选框正常工作:

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

希望这可以帮助您或其他任何偶然发现此问题的人。

另外,原谅我的Java noobness ......我几周前才开始使用Java。

答案 1 :(得分:3)

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

List11.java SDK示例演示了这一点。您还可以从我的一个使用它的教程中找到一个项目here

您仍然可以将此技术用于您自己的布局,只要您在CheckedTextView资源中添加android:id="@android:id/text1" android.R.layout.simple_list_item_multiple_choice,其中包含SDK的副本

另请参阅this questionthis question以及this questionthis question

答案 2 :(得分:1)

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

                  }
              });

在主要活动之后你必须检查复选框的哪个位置是真的

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 :(得分:0)

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();

      }
    });

  }
}

答案 4 :(得分:-1)

  1. 复选框 打开“res / layout / main.xml”文件,在LinearLayout中添加3个“CheckBox”和一个按钮。
  2. 文件: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>