【问题标题】:Android save Checkbox State in ListView with Cursor AdapterAndroid 使用光标适配器在 ListView 中保存复选框状态
【发布时间】:2011-01-25 07:16:27
【问题描述】:

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

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

【问题讨论】:

    标签: android listview checkbox state


    【解决方案1】:

    我建议您使用 Android 对多项选择列表的内置支持 (CHOICE_MODE_MULTIPLE)。

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

    您仍然可以将此技术与您自己的布局一起使用,只要您在 android:id="@android:id/text1" 中包含 CheckedTextView,如 android.R.layout.simple_list_item_multiple_choice 资源中所示,您的 SDK 附带了该资源的副本。

    另外,请参阅 this questionthis questionthis questionthis question

    【讨论】:

    • 我将如何使用我自己的布局? checktextview 不需要是该行的顶层吗?当我使用checkedtextview时,我似乎找不到添加所需视图的方法,例如ImageView来显示图像(来自相机的照片)。
    • 首先,CheckedTextView 支持 android:drawableLeft 和 kin,您可以使用它们。其次,AFAIK,只要它有正确的android:id(见上文),它就可以在其他布局中(例如,LinearLayout 也涉及ImageView)。
    • 现在我似乎遇到了与此线程 mail-archive.com/android-beginners@googlegroups.com/… 相同的问题。我如何从后面的代码中设置 android:drawableLeft 属性?
    • 致电setCompoundDrawables()setCompoundDrawablesWithIntrinsicBounds() 中的一种
    • 感谢您的帮助。我决定使用多选方法,只使用 xml 中的 CheckedTextView 并通过 setCompoundDrawablesWithIntrinsicBounds() 添加图像。使用 CheckedTextView 的其他视图时仍然无法使布局正常工作,但这可以。对于应该相对简单的事情来说,这太麻烦了。再次感谢。
    【解决方案2】:

    我自己也有同样的问题:如何在自定义布局中切换多选 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 菜鸟……我几周前才开始使用 Java。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:
        1. 复选框 打开“res/layout/main.xml”文件,在LinearLayout里面添加3个“CheckBox”和一个按钮。

        文件: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>
        

        【讨论】:

          【解决方案5】:
          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();
          
                }
              });
          
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2015-09-28
            • 1970-01-01
            • 1970-01-01
            • 2013-01-28
            • 2015-06-17
            • 2013-06-12
            • 2021-09-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多