2009-10-01 14 views
43

Sto tentando di collegare i dati dal mio SQLiteDatabase a un ListView. Attualmente sto usando un SimpleCursorAdapter per compilare il mio ListView. Sfortunatamente questo non sembra funzionare con l'impostazione dell'attributo checked di CheckBox.Android: collegamento di dati da un database a un CheckBox in un controllo ListView?

Ecco come lo faccio ora; invece di modificare lo stato controllato del CheckBox, l'adattatore sta inserendo il valore nell'argomento di testo, quindi il valore viene visualizzato a destra del CheckBox come testo.

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: Il campo del database è naturalmente di tipo booleano e ho anche cercato di assegnare un ID al controllato campo per riempire il valore.

risposta

33

Non sono sicuro di come si farebbe a parte la creazione di un adattatore personalizzato che sovrascrive newView/bindView o getView, a seconda di ciò che si sovrascrive (ResourceCursorAda pter è buono).

Ok, ecco un esempio. Non ho prove per vedere se avrebbe compilato perché io sono al lavoro, ma questo dovrebbe sicuramente il punto è nella giusta direzione:

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

Potresti darmi un esempio, perché sono davvero nuovo nella programmazione Android e non ho ancora visto qualcosa di simile? – svens

+0

Certo, dimmi qualcosa e lo posterò. – MattC

+0

Grazie !! Ha funzionato. Sembra che non ci sia la funzione getBoolean() ;-) .. Sto usando cbListCheck.setChecked ((cur.getInt (cur.getColumnIndex (Datenbank.DB_STATE)) == 0? False: true)); che fa il trucco. – svens

38

È possibile impostare una consuetudine 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; 
    } 
}); 

Il metodo setViewValue viene invocato per ogni colonna specificata nel costruttore SimpleCursorAdapter e offre una buona posizione per manipolare alcune (o tutte) le viste.

+3

L'unico problema è che questo non è disponibile in api livello 3 (Android 1.5). Questo è disponibile dal livello api 5. –

+1

Questa tecnica ha funzionato molto bene per me per ottenere immagini caricate in una visualizzazione elenco. Grazie. –

+4

I documenti dicono disponibili dal livello 1 dell'API. Inoltre, dovrebbe essere abbastanza sicuro raggiungere il livello 5 e ora: http://developer.android.com/resources/dashboard/platform-versions.html – plainjimbo

0

È possibile risolvere questo problema con la creazione di un widget CheckBox personalizzato in questo modo:

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 funzione OnTextChanged verrà chiamato quando ListView si lega i dati alla casella di controllo (cioè aggiungendo uno "0" o ". 1"). Questo catturerà questa modifica e aggiungerà il tuo processo booleano. La prima frase "se" è necessaria in modo da non creare una ricorsione infinita.

quindi fornire la classe personalizzata per il file di layout in quanto tale:

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

Che dovrebbe farlo!

+0

Mi piace questa implementazione meglio, tuttavia quando lo provo, il mio programma si arresta in modo anomalo quando tenta di gonfiare il mio oggetto CustomCheckBox. Perché dovrebbe essere? – finiteloop

+0

Questa soluzione non funziona per me. – petrnohejl

Problemi correlati