wake-up-neo.com

Android: Daten aus einer Datenbank an eine CheckBox in einer ListView binden?

Ich versuche, Daten von meinem SQLiteDatabase an ein ListView zu binden. Ich verwende derzeit ein SimpleCursorAdapter, um mein ListView auszufüllen. Leider scheint dies nicht zu funktionieren, wenn das Häkchen-Attribut einer CheckBox gesetzt wird.

So mache ich es jetzt; Anstatt den aktivierten Status des Kontrollkästchens zu ändern, fügt der Adapter den Wert in das Textargument ein, sodass der Wert rechts neben dem Kontrollkästchen als Text angezeigt wird.

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>

Bearbeiten: Das Feld in der Datenbank ist natürlich vom Typ Boolesch und ich habe auch versucht, dem markierten Feld eine ID zuzuweisen, um den Wert auszufüllen.

43
svens

Ich bin nicht sicher, wie Sie dies tun würden, abgesehen von der Erstellung eines benutzerdefinierten Adapters, der newView/bindView oder getView überschreibt, je nachdem, was Sie überschreiben (ResourceCursorAdapter ist ein guter Adapter).

Ok, hier ist ein Beispiel. Ich habe nicht getestet, ob es kompiliert werden kann, weil ich auf der Arbeit bin, aber dies sollte auf jeden Fall in die richtige Richtung weisen:

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

Sie könnten eine benutzerdefinierte 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;
    }
});

Die Methode setViewValue wird für jede Spalte aufgerufen, die Sie im Konstruktor SimpleCursorAdapter angeben, und bietet Ihnen eine gute Möglichkeit, einige (oder alle) Ansichten zu bearbeiten.

37
Josef Pfleger

Sie können dieses Problem lösen, indem Sie ein benutzerdefiniertes CheckBox-Widget wie folgt erstellen:

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

Die onTextChanged-Funktion wird aufgerufen, wenn die ListView die Daten an die CheckBox bindet (dh entweder "0" oder "1" hinzufügt). Dies fängt diese Änderung ab und fügt sie in Ihre boolesche Verarbeitung ein. Die erste "if" -Anweisung wird benötigt, um keine unendliche Rekursion zu erzeugen.

Geben Sie dann Ihre benutzerdefinierte Klasse in die Layoutdatei als solche ein:

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

Das sollte es tun!

0
Nick