web-dev-qa-db-fra.com

Android: Lier des données d'une base de données à une CheckBox dans un ListView?

J'essaie de lier des données de mon SQLiteDatabase à un ListView. J'utilise actuellement un SimpleCursorAdapter pour remplir mon ListView. Malheureusement, cela ne semble pas fonctionner avec la définition de l'attribut vérifié d'une CheckBox.

Voilà comment je le fais maintenant; au lieu de modifier l'état vérifié de la CheckBox, l'adaptateur remplit la valeur de l'argument texte, de sorte que la valeur s'affiche à droite de la CheckBox sous forme de texte.

Java:

setListAdapter( new SimpleCursorAdapter( this,
      R.layout.mylist,
      data,
      new String[] { Datenbank.DB_STATE, Datenbank.DB_NAME },
      new int[] { R.id.list_checkbox, R.id.list_text }
    ) );

mylist.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout Android:id="@+id/LinearLayout01"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
xmlns:Android="http://schemas.Android.com/apk/res/Android"
>

<CheckBox Android:text=""
    Android:id="@+id/list_checkbox"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:checked="false"
    ></CheckBox>

<TextView Android:text=""
    Android:id="@+id/list_text"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    ></TextView>

</LinearLayout>

Edit: Le champ dans la base de données est bien sûr de type booléen et j'ai également essayé d'attribuer un identifiant au champ coché pour remplir la valeur.

43
svens

Je ne sais pas comment vous feriez cela en dehors de la création d'un adaptateur personnalisé qui a remplacé newView/bindView ou getView, selon ce que vous remplacez (ResourceCursorAdapter est un bon).

Ok, voici donc un exemple. Je n'ai pas testé pour voir si cela se compilerait parce que je suis au travail, mais cela devrait certainement vous orienter dans la bonne direction:

public class MyActivity extends ListActivity {

    MyAdapter mListAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Cursor myCur = null;

        myCur = do_stuff_here_to_obtain_a_cursor_of_query_results();

        mListAdapter = new MyAdapter(MyActivity.this, myCur);
        setListAdapter(mListAdapter);
    }


    private class MyAdapter extends ResourceCursorAdapter {

        public MyAdapter(Context context, Cursor cur) {
            super(context, R.layout.mylist, cur);
        }

        @Override
        public View newView(Context context, Cursor cur, ViewGroup parent) {
            LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            return li.inflate(R.layout.mylist, parent, false);
        }

        @Override
        public void bindView(View view, Context context, Cursor cur) {
            TextView tvListText = (TextView)view.findViewById(R.id.list_text);
            CheckBox cbListCheck = (CheckBox)view.findViewById(R.id.list_checkbox);

            tvListText.setText(cur.getString(cur.getColumnIndex(Datenbank.DB_NAME)));
            cbListCheck.setChecked((cur.getInt(cur.getColumnIndex(Datenbank.DB_STATE))==0? false:true))));
        }
    }
}
33
MattC

Vous pouvez définir une personnalisation SimpleCursorAdapter.ViewBinder :

SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(/* ur stuff */);
cursorAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        if(columnIndex == 1) {
            CheckBox cb = (CheckBox) view;
            cb.setChecked(cursor.getInt(1) > 0);
            return true;
        }
        return false;
    }
});

La méthode setViewValue est invoquée pour chaque colonne que vous spécifiez dans le constructeur SimpleCursorAdapter et vous permet de manipuler une partie (ou la totalité) des vues.

37
Josef Pfleger

Vous pouvez résoudre ce problème en créant un widget CheckBox personnalisé comme ceci:

package com.example.CustomCheckBox;    
public class CustomCheckBox extends CheckBox {
     public CustomCheckBox(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
     }
     public CustomCheckBox(Context context, AttributeSet attrs) {
      super(context, attrs);
     }
     public CustomCheckBox(Context context) {
      super(context);
     }
     protected void onTextChanged(CharSequence text, int start, int before, int after) {
      if (text.toString().compareTo("") != 0) {
       setChecked(text.toString().compareTo("1") == 0 ? true : false);
       setText("");
      }
     }
    }

La fonction onTextChanged sera appelée lorsque ListView lie les données à la CheckBox (c'est-à-dire en ajoutant "0" ou "1"). Cela va attraper ce changement et ajouter à votre traitement booléen. La 1ère instruction "if" est nécessaire pour ne pas créer de récursion infinie.

Fournissez ensuite votre classe personnalisée dans le fichier de mise en page en tant que telle:

<com.example.CustomCheckBox
 Android:id="@+id/rowCheckBox"
 Android:layout_height="fill_parent"
 Android:layout_width="wrap_content" />

Ça devrait le faire!

0
Nick