Pregunta

Estoy intentando implementar una lista de "cosas por hacer" muy simple.Elegí usar un ListView de CheckedTextView (con id. check_text), ListView usa CHOICE_MODE_MULTIPLE, por supuesto.

Ahora estoy usando la base de datos SQLite para almacenar los elementos de la lista.

Para llenar la lista tengo algo como:

cursor = dbHelper.fetchAll();
startManagingCursor(cursor);

String[] from = new String[] {  DbAdapter.NAME };
int[] to = new int[] { R.id.checked_text };

SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.todo_multi_row, cursor, from, to);
listView.setAdapter(notes);

Esto está funcionando bien, obtiene todos los elementos en el DB y para cada elemento crea una View CheckedText con como texto dbadapter.name.

Pero lo que realmente necesito es obtener tanto el texto como el estado marcado, y verificar las filas en consecuencia.

Digamos que puedo obtener el estado (como Integer 0/1) del DB usando DBADAPTER.COLKED ..¿Cómo puedo implementar un adaptador de cursor que haga el trabajo?

Busqué por todas partes (por ejemplo esta pregunta lo cual es un desastre) pero no encontré nada para resolver este problema.Vaya.Al principio parecía muy fácil.

Gracias,
estefano


@Bert F:
Gracias, este es el método que estoy usando para completar mi lista:

private void fillData() {
        Log.d("LIST","fill");
        cursor = dbHelper.fetchAllTodos();
        startManagingCursor(cursor);

        String[] from = new String[] { TodoDbAdapter.NAME };
        int[] to = new int[] { R.id.checked_text };

        SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
                R.layout.todo_multi_row, cursor, from, to);

        final SimpleCursorAdapter.ViewBinder mViewBinder =
            new SimpleCursorAdapter.ViewBinder() {
                @Override
                public boolean setViewValue(
                        final View view,
                        final Cursor cursor,
                        final int columnIndex) {

                    Log.d("LIST",view +" "+cursor+" "+columnIndex);

                    CheckedTextView item = (CheckedTextView) view;
                    Log.d("LIST","NAME: "+item.getText()+" State: "+item.isChecked());

                    return false;
                }
            };

        notes.setViewBinder(mViewBinder);
        listView.setAdapter(notes);
    }

Ahora, como prueba, simplemente estoy imprimiendo lo que está sucediendo.
Si agrego 1 elemento a la lista lo que veo es:

02-12 14:45:35.913: DEBUG/LIST(22621): fill
02-12 14:45:35.933: DEBUG/LIST(22621): android.widget.CheckedTextView@479da398 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:35.933: DEBUG/LIST(22621): NAME:  State: false
02-12 14:45:35.933: DEBUG/LIST(22621): android.widget.CheckedTextView@479da398 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:35.943: DEBUG/LIST(22621): NAME: first item State: false
02-12 14:45:36.013: DEBUG/LIST(22621): android.widget.CheckedTextView@479dc6c0 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:36.013: DEBUG/LIST(22621): NAME:  State: false
02-12 14:45:36.223: DEBUG/LIST(22621): android.widget.CheckedTextView@479dc6c0 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:45:36.223: DEBUG/LIST(22621): NAME: first item State: false

Y si lo reviso..

02-12 14:53:33.123: DEBUG/LIST(22621): android.widget.CheckedTextView@479dc6c0 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:53:33.123: DEBUG/LIST(22621): NAME: first item State: false
02-12 14:53:33.123: DEBUG/LIST(22621): android.widget.CheckedTextView@479da398 android.database.sqlite.SQLiteCursor@479d98f0 2
02-12 14:53:33.123: DEBUG/LIST(22621): NAME: first item State: false

Dejando de lado el hecho de que dice que no está marcado, ¿por qué dispara tantas veces?Solo tengo 1 artículo :I


EDITAR:solución fea

private void fillData() {
        Log.d("LIST","fill");
        cursor = dbHelper.fetchAllTodos();
        startManagingCursor(cursor);

        String[] from = new String[] { TodoDbAdapter.NAME };
        int[] to = new int[] { R.id.checked_text };

        SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
                R.layout.todo_multi_row, cursor, from, to);

        final SimpleCursorAdapter.ViewBinder mViewBinder =
            new SimpleCursorAdapter.ViewBinder() {
                @Override
                public boolean setViewValue(
                        final View view,
                        final Cursor cursor,
                        final int columnIndex) {

                     final int checkedIndex =
                         cursor.getColumnIndexOrThrow(
                                 TodoDbAdapter.CHECKED);

                     Log.d("LIST","VIEW: "+view+" NAME: "+cursor.getString(columnIndex)+" "+cursor.getInt(checkedIndex));

                    return false;
                }
            };

        notes.setViewBinder(mViewBinder);
        listView.setAdapter(notes);
    }

Con 2 entradas (la primera seleccionada y la segunda no) cuando cargo la lista tengo:

02-12 15:59:48.613: DEBUG/LIST(23533): fill
02-12 15:59:48.643: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a30ec0 NAME: test 1
02-12 15:59:48.653: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a30ec0 NAME: LOL 0
02-12 15:59:48.683: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a30ec0 NAME: test 1
02-12 15:59:48.683: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a331f8 NAME: LOL 0
02-12 15:59:48.713: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: test 1
02-12 15:59:48.713: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: LOL 0
02-12 15:59:48.783: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: test 1
02-12 15:59:48.783: DEBUG/LIST(23533): VIEW: android.widget.CheckedTextView@47a35770 NAME: LOL 0

Salud.

¿Fue útil?

Solución

  1. Implementar un SimpleCursorAdapter.ViewBinder.

  2. Tener el ViewBinder.setViewValue() método de verificación para cuándo se llama para el DbAdapter.NAME columna o haga que verifique la R.id.checked_text-tipo vista.

  3. Cuando llamó, pero no por no la columna/vista de destino, haga que regrese false para que el adaptador vincule la columna/vista como lo haría normalmente.

  4. Cuando solicitó la columna/vista de destino, haga que establezca el texto y la casilla de verificación para el (CheckedTextView) view.debería terminar regresando true para que el adaptador no continúe intentando vincular la vista en sí.Tenga en cuenta que el cursor está disponible para acceder a los datos de la consulta para determinar si se debe marcar la casilla de verificación o no (DbAdapter.CHECKED).

  5. Establecer su ViewBinder en tus SimpleCursorAdapter a través de setViewBinder()

Aquí está una de mis implementaciones de ViewBinder.No es para casillas de verificación, sino para dar formato elegante a una vista de texto, pero debería darle una idea del enfoque:

private final SimpleCursorAdapter.ViewBinder mViewBinder =
    new SimpleCursorAdapter.ViewBinder() {
        @Override
        public boolean setViewValue(
                final View view,
                final Cursor cursor,
                final int columnIndex) {
            final int latitudeColumnIndex =
                cursor.getColumnIndexOrThrow(
                        LocationDbAdapter.KEY_LATITUDE);
            final int addressStreet1ColumnIndex =
                cursor.getColumnIndexOrThrow(
                        LocationDbAdapter.KEY_ADDRESS_STREET1);

            if (columnIndex == latitudeColumnIndex) {

                final String text = formatCoordinates(cursor);
                ((TextView) view).setText(text);
                return true;

            } else if (columnIndex == addressStreet1ColumnIndex) {

                final String text = formatAddress(cursor);
                ((TextView) view).setText(text);
                return true;

            }

            return false;
        }
    };
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top