Depuración de SimpleCursorAdapter

Estoy trabajando en mi primera aplicación de Android y no puedo averiguar cómo obtener mi SimpleCursorAdpater para rellenar la vista. El cursor que estoy pasando en tiene resultados en él, por lo que el problema debe estar en algún lugar en instanciar el adaptador o en vinculante a la vista. Estoy un poco en mi ingenio final ya que no se lanzan excepciones y realmente no puedo entrar en setListAdapter.

Aquí es cómo consigo mi cursor en el primer lugar:

  Searches searches = new Searches(this); SQLiteDatabase db = searches.getReadableDatabase(); //select _id, Name, Search FROM Searches; Cursor c = db.query( SearchConstants.TABLE_NAME, FROM, null, null, null, null, null); startManagingCursor(c); 

Y este es el esquema de mi db:

 CREATE TABLE Searches (_id INTEGER PRIMARY KEY, Name Text, Search TEXT) 

Aquí están las dos líneas donde las cosas empiezan a desmoronarse:

 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.search, cursor, FROM, TO); setListAdapter(adapter); 

Mi diseño principal se ve así:

 <ListView android:id="@android:id/android:list" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@android:id/android:empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/empty" /> 

Aquí está la vista para llenar con cada resultado:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10sp"> <TextView android:id="@+id/_id" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/colon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=": " android:layout_toRightOf="@id/name" /> <TextView android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:textStyle="italic" android:layout_toRightOf="@id/colon" /> </RelativeLayout> 

Finalmente aquí están las variables estáticas que usé:

 //search query stuff private static String[] FROM = {SearchConstants._ID, SearchConstants.NAME_COLUMN, SearchConstants.SEARCH_COLUMN}; //where to paste search results private static int[] TO = {R.id._id, R.id.name, R.id.search}; /** * Table name */ public static final String TABLE_NAME = "Searches"; /** * Name Column */ public static final String NAME_COLUMN = "Name"; /** * Search Column */ public static final String SEARCH_COLUMN = "Search"; 

Creo que esto es todo el código relevante. No tengo ni idea de cómo proceder en este momento, por lo que cualquier sugerencia en todo sería útil.

Gracias, brian

PS: Parece que hay un montón de grandes sugerencias aquí – no estoy ignorándolos i havent ha tenido la oportunidad todavía. ¡Gracias por el consejo! En algún momento voy a ir a través de todos ellos y tratar de dar algunas sugerencias sobre qué cosas funcionaron bien para mí.

Puede entrar en el código si tiene el código fuente. Por suerte, Android es de código abierto. Para adjuntar fácilmente código fuente en Eclipse, consulte:

http://android.opensourceror.org/2010/01/18/android-source/

En cuanto al problema en sí, dijo en un comentario anterior que iterar todos los elementos antes de crear el adaptador. Si no está creando un cursor nuevo después de la iteración, es probable que necesite rebobinarlo o el adaptador podría pensar que está vacío.

 cursor.moveToFirst() 

Por favor, no se preocupe por ningún aspecto interno vinculante. Estoy seguro de que hay una salida fácil. Pruebe lo siguiente: En primer lugar, sólo para asegurarse de que su cursor realmente tiene datos donde es necesario, coloque la línea

 System.out.println("cursor.getCount()="+cursor.getCount()); 

justo antes de la llamada de setAdapter (). Pero seguramente, ya probaste para obtener un recuento de filas 😉 Así que lo siguiente podría ser más interesante.

Para comprobar si su enlace falla, pruebe con:

 android:id="@+id/android:list" 

en lugar de :

 android:id="@android:id/android:list" 

en su main.xml. Lo mismo con: android: id = "@ + id / android: empty".

Y si todavía no obtiene resultados, también puede intentar usar una lista por defecto xml-layout (como simple_list_item_1) para mostrar, que se vería así:

 ListAdapter adapter = new SimpleCursorAdapter(this, // Use a template that displays a text view android.R.layout.simple_list_item_1, // Give the cursor to the list adapter cursor, // Map the NAME column in your database to... new String[] {SearchConstants.NAME_COLUMN} , // ...the "text1" view defined in the R.layout.simple_list_item_1 new int[] {android.R.id.text1} ); 

Sólo copie lo pegar en su actividad y ver qué pasa. Espero que haya terminado con eso!

Recibí el mismo problema y encontré cómo permitir que la creación de Simplecursoradapter no fallara.

En su cursor, la consulta de la base de datos DEBE contener la clave primaria de la tabla, incluso si no lo necesita! Si no, fallará y se bloqueará …

Espero que ayude a otros con el mismo problema!

Muy bien, me di cuenta de que usó un nombre de columna con una letra mayúscula. Asegúrese de utilizar el identificador exacto en el esquema DB (los nombres de columna sqlite son sensibles a mayúsculas y minúsculas). Pero en el código que proporcionó los identificadores de columna coinciden.

Por lo tanto, si el cursor que utiliza realmente tiene los datos, pruebe el código anterior al principio (en lugar de algún diseño personalizado) para crear un SimpleCursorAdapter y debería funcionar. Aquí hay otro pequeño ejemplo para el código de actividad (como yo no conozco el tuyo):

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.dbManager = new DatabaseManager(this); setContentView(R.layout.main); registerForContextMenu(getListView()); // catch clicks if (!showList()) { TextView tv = new TextView(this); tv.setText(getString(R.string.txt_list_empty)); setContentView(tv); } } private boolean showList() { final Cursor c = dbManager.fetchListData(); startManagingCursor(c); // when the Activity finishes, the cursor is closed if (!c.moveToFirst()) return false; final SimpleCursorAdapter myAdapter = new SimpleCursorAdapter( this, android.R.layout.simple_list_item_2, c, new String[]{"name"} , new int[]{android.R.id.text1} ); setListAdapter(myAdapter); return true; } 

Antes de pasar mucho tiempo donde se encuentran los problemas, más bien empezar donde las cosas siguen funcionando y tomar pequeños pasos para las extensiones. Si usted los mantiene simples, no hay gran magia en el uso de adaptadores.

Puede intentar insertar un ViewBinder para depurar. Puede utilizarlo para inspeccionar qué valores se pasan para qué vistas en el SimpleCursorAdaptor. O simplemente usarlo para hacer manualmente el enlace usted mismo.

Algo así debería funcionar:

 adapter.setViewBinder(new SimpleCursorBinder()); 

y entonces

 public class SimpleCursorBinder implements SimpleCursorAdpater.ViewBinder { public boolean setViewValue(View view, Cursor cursor, int columnIndex) { /* set breakpoints and examine incoming data. */ // returning false, causes SimpleCursorAdapter to handing the binding boolean bound = false; String columnName = cursor.getColumnName(columnIndex); TextView bindingView = null; int viewId = view.getId(); // could just use this opportunity to manually bind if (columnName.equals(SearchConstants._ID)) { bindingView = (TextView)(viewId == R.id._id ? view : null); } else if (columnName.equals(SearchConstants.NAME_COLUMN)) { bindingView = (TextView)(viewId == R.id.name ? view : null); } else if (columnName.equals(SearchConstants.SEARCH_COLUMN)) { bindingView = (TextView)(viewId == R.id.search ? view : null); } if (bindingView != null) { bindingView.setText(cursor.getString(columnIndex)); bound = true; } return bound; } } 

No parece que hayas hecho nada malo, pero no has mostrado todo tu código, así que puede ser difícil detectar errores.

No estoy seguro de si la línea startManagingCursor (c) hace esto por usted, pero en mis ejemplos tengo las siguientes líneas después de que mi consulta se ha completado. Dado su ejemplo se ve absolutamente bien podría ser su cursor necesita restablecer el primer elemento.

(Ah, sólo noté kichik señaló esto, pero voy a dejar mi ejemplo.)

 if (c != null) { c.moveToFirst(); } 

Mis consultas suelen tener el siguiente aspecto:

 public Cursor getQueryCursor() { Cursor c; c = null; try{ c = myDataBase.query(TABLE_MYTABLE, new String[] { COLUMN_ID,COLUMN_LABEL, COLUMN_TEXT}, null, null, null, null, null); if (c != null) { c.moveToFirst(); } }catch(Exception ec) { Log.w("MY_APP", ec.getMessage()); } return c; } 

Luego, al aplicar el resultado de la consulta, también pongo a menudo declaraciones try / catch a su alrededor y añade puntos de quiebre en estos puntos (a veces getMessage () devuelve null pero otras propiedades de la excepción resaltarán el problema. A menudo he sido capaz de resolver la raíz de mis problemas con lo siguiente.

 try{ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.search, cursor, FROM, TO); setListAdapter(adapter); }catch(IllegalStateException e) { Log.w("MyApp", e.getMessage()); }catch(Exception es) { Log.w("MyApp", es.getMessage()); } 

Compruebe su base de datos SQLite, debe tener una columna '_id' como clave principal. Tuve el mismo tipo de problema, y ​​finalmente averiguarlo con esto …

  • Android ListView con el botón de opción
  • ListView: excepción de puntero nulo
  • BaseAdapter ListView Filtrado de Android
  • Obtener un evento cuando un elemento ListView está visible o no
  • Añadir imagen de perfil a la vista de lista en el cajón de navegación
  • Encuadernación onScrolling escucha al android ListView
  • Agregar un elemento CheckBox a ListView impide que pueda recibir ItemClick
  • Creación de un RecyclerView ampliable
  • Cómo crear una tarjeta de estilo android estilo listview
  • Casilla de verificación en CursorAdapter
  • Android: consigue la posición del elemento en un listview dado su id:
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.