Android: lier des données d'une base de données à une case à cocher dans une 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 le réglage de l'attribut vérifié d'une case à cocher.

c'est comme ça que je le fais maintenant; au lieu de changer l'état vérifié de la case à cocher, l'adaptateur remplit la valeur dans l'argument texte, donc la valeur est affichée à droite de la case à cocher en tant que 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 }
    ) );

maliste.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 aussi essayé d'assigner un id au champ coché pour remplir la valeur.

43
demandé sur Bishan 2009-10-01 22:46:30
la source

3 ответов

Je ne suis pas sûr de savoir comment vous feriez cela, à part créer un adaptateur personnalisé qui surpasse newView/bindView ou getView, selon ce que vous outrepassez (ResourceCursorAdapter est un bon Adaptateur).

Ok, donc voici un exemple. Je n'ai pas testé pour voir s'il compilerait parce que je suis au travail, mais cela devrait certainement vous pointer 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
répondu MattC 2009-10-02 01:43:59
la source

vous pouvez définir une coutume 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 donne un bon endroit pour manipuler une partie (ou la totalité) des vues.

37
répondu Josef Pfleger 2009-11-28 16:53:52
la source

vous pouvez résoudre ce problème en créant un widget checkbox personnalisé comme suit:

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 reliera les données à la case à cocher (c.-à-d. Ajouter "0"ou " 1"). Cela va attraper ce changement et ajouter dans votre traitement booléen. La 1ère instruction " Si " est nécessaire pour ne pas créer une récursion infinie.

puis fournir votre classe personnalisée dans le fichier de mise en page comme tel:

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

Qui devrait le faire!

0
répondu Nick 2010-01-26 03:33:47
la source

Autres questions sur android listview checkbox cursor