2010-03-09 8 views
7

Je ne trouve pas un moyen d'enregistrer l'état de la case à cocher lorsque vous utilisez un adaptateur Cursor. Tout le reste fonctionne bien mais si je clique sur une case à cocher il est répété quand il est recyclé. J'ai vu des exemples en utilisant des adaptateurs de tableau mais à cause de mon manque d'expérience, j'ai du mal à le traduire en utilisant un adaptateur de curseur. Quelqu'un pourrait-il me donner un exemple de la façon de s'y prendre? Toute aide appréciée.Android enregistrer État de la case à cocher dans ListView avec l'adaptateur de curseur

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

Répondre

3

Je vous recommande d'utiliser Android de support intégré pour les listes à choix multiples (CHOICE_MODE_MULTIPLE).

L'échantillon SDK List11.java démontre. Vous pouvez également trouver un projet d'un de mes tutoriels qui l'utilise here.

Vous pouvez toujours utiliser cette technique avec votre propre mise en page, à condition d'inclure un CheckedTextView avec android:id="@android:id/text1" comme indiqué dans la ressource android.R.layout.simple_list_item_multiple_choice, dont une copie est fournie avec votre SDK.

Voir aussi this question et this question et this question et this question.

+1

Comment puis-je utiliser ma propre mise en page? doesnt le checkedtextview doit-il être le plus haut niveau de la rangée? Je ne peux pas sembler trouver un moyen d'ajouter les vues dont j'ai besoin d'avoir, comme un ImageView pour montrer une image (photo de la caméra), quand j'utilise une vue de texte cochée. – Ricardo

+0

Tout d'abord, 'CheckedTextView' supporte' android: drawableLeft' et kin, que vous pourriez utiliser. Deuxièmement, AFAIK, tant qu'il a le bon 'android: id' (voir ci-dessus), il peut être dans une autre disposition (par exemple, un' LinearLayout' impliquant également un 'ImageView'). – CommonsWare

+0

maintenant, je semble avoir le même problème que dans ce fil http://www.mail-archive.com/[email protected]/msg06941.html. Comment est-ce que je placerais la propriété android: drawableLeft du code derrière? – Ricardo

4

J'ai eu le même problème moi-même: comment basculer plusieurs sélectionnez CheckedTextView dans une mise en page personnalisée (i.e. ne pas utiliser android.R.layout.simple_list_item_multiple_choice)

Ce qui suit a fonctionné pour moi. L'exemple que j'ai est une vue personnalisée qui est fourni un adaptateur étendu de SimpleCursorAdapter.

Mon point de vue personnalisé (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> 

L'adaptateur est créé dans ListActivity.OnCreate, qui appelle 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); 
    } 

L'adaptateur personnalisé:

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

    } 

Le bit crucial de code pour moi était d'obtenir des cases à cocher travailler était:

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

Espérons que cela vous aide, vous ou quelqu'un d'autre qui trébuche sur cette question.

Aussi, mon pardon Java noobness ... Je n'ai commencé Java il y a quelques semaines.

1

Déclare la case getView Méthode et en utilisant ce code

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

        } 
       }); 

Après que la principale activité u ont pour vérifier que la position de la case est vrai

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 
       } 

      }}); 
-1
  1. CheckBox Ouvrir « res/layout/main.xml » fichier, ajoutez 3 « checkbox » et un bouton, à l'intérieur du LinearLayout.

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

     } 
    }); 

    } 
}