No se pudo leer la fila 1, col -1 de CursorWindow. Asegúrese de que el cursor se inicialice correctamente antes de acceder a los datos de él
Im implementación de un ExpandableListView y para cada grupo, muestra el childs, y cada niño con su propia duración, y el grupo muestra la suma de todas las duraciones de los childs.
Sin embargo, cuando hago clic en un niño muestra el error:
- Multi-layered ExpandableListView
- Android ExpandableListView Parent con botón
- ExpandableListView getChildrenCount no se llama después de los datos cambiados, dando lugar a IndexOutOfBoundsException
- ExpandableListView muestra el indicador para grupos sin hijos
- Deslice el efecto hacia abajo en ExpandableListView
No se pudo leer la fila 1, col -1 de CursorWindow. Asegúrese de que el Cursor se inicializa correctamente antes de acceder a los datos de él.
Y no estoy llamando al método setOnChildClickListener
. E incluso si lo llamo, cuando hago clic en el niño, no se detiene en él cuando pongo un punto de interrupción.
Este es el problema, no puedo encontrar donde está el error, ya que el stacktrace no apunta a las clases de mi proyecto, sino a la clase native de android. He intentado poner puntos de interrupción en cada parte de mi código, pero cuando hago clic en un niño, no se alcanza ninguno de los puntos de interrupción.
Por cierto, estoy usando el patrón ViewHolder para tratar con las vistas, y el adaptador es un CursorTreeAdapter
Aquí está mi código – y el stacktrace completo está al final :
public class MyClass extends ExpandableListActivity { private Cursor mContactsCursor; private ExpandableListView mExpandableListView; private Integer mContactId; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.contacts_layout); mExpandableListView.setOnGroupClickListener(new OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { mContactId = Integer.parseInt(v.getTag(R.id.contact_name).toString()); return false; } }); } @Override public void onResume() { super.onResume(); mContactsCursor = mController.getContacts(); mExpandableListView.setAdapter(new ContactsExpandableListAdapter(mContactsCursor, this)); } @Override public void onPause() { super.onPause(); if(!mContactsCursor.isClosed()) mContactsCursor.close(); } @Override public void onDestroy() { super.onDestroy(); if(!mContactsCursor.isClosed()) mContactsCursor.close(); } public class ContactsExpandableListAdapter extends CursorTreeAdapter { private TextView mContactNameTextView, mContactNumberTextView, mDurationTextView; public ContactsExpandableListAdapter(Cursor cursor, Context context) { super(cursor, context); } @Override protected Cursor getChildrenCursor(Cursor groupCursor) { return mController.getContactById(mContactId); } @Override protected View newGroupView(Context context, Cursor cursor, boolean isExpanded, ViewGroup viewGroup) { View view = LayoutInflater.from(context).inflate(R.layout.listitem_contacts, viewGroup, false); ViewHolder viewHolder = new ViewHolder(); viewHolder.contactName = (TextView) view.findViewById(R.id.contact_name); viewHolder.duration = (TextView) view.findViewById(R.id.duration); viewHolder.groupIndicator = (ImageView) view.findViewById(R.id.indicator_icon); viewHolder.contactName.setText(cursor.getString(cursor.getColumnIndex("contact_name"))); // Set the duration to the view viewHolder.duration.setText(cursor.getString(cursor.getColumnIndex("duration_sum"))); // Set the tags to the view to be used later when the user click the group view. // These tags are the contact number, contact id and the the view holder object // to be retrieved when binding the group view view.setTag(R.id.contact_number, cursor.getString(cursor.getColumnIndex("contact_number"))); view.setTag(R.id.rlt_main, viewHolder); view.setTag(R.id.contact_name, cursor.getString(cursor.getColumnIndex("contact_id"))); } return view; } @Override protected View newChildView(Context context, Cursor cursor, boolean isLastChild, ViewGroup viewGroup) { View view = LayoutInflater.from(context).inflate(R.layout.listitem_contacts, viewGroup, false); mContactNumberTextView = (TextView) view.findViewById(R.id.phone_number); mContactNumberTextView.setText(cursor.getString(cursor.getColumnIndex("contact_name"))); mDurationTextView = (TextView) view.findViewById(R.id.duration); mDurationTextView.setText(cursor.getString(cursor.getColumnIndex("duration"))); view.setTag(cursor.getString(cursor.getColumnIndex("contact_number"))); return view; } @Override protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) { ViewHolder viewHolder = (ViewHolder) view.getTag(R.id.rlt_main); // For each view created, make a query to the database based on the contact id. // This is not very wise to do, but will probably be changed in the future. Integer contactId = cursor.getInt(cursor.getColumnIndex("contact_id")); // Check if the current contact id is equal to -1. If yes it means the contact Cursor currentContactCursor = mFilterByContactController.getContactById(contactId); // Check if the cursor being retrieved from the database based on the current view cursor // is major than zero. If yes, it means it has children, so set the indicator icon to this // view as visible. If not, set the indicator for this view as gone. if(currentContactCursor != null && currentContactCursor.getCount() > 0) { viewHolder.groupIndicator.setVisibility(View.VISIBLE); viewHolder.groupIndicator.setImageResource(isExpanded ? R.drawable.expander_ic_maximized : R.drawable.expander_ic_minimized); } else { viewHolder.groupIndicator.setVisibility(View.GONE); } if(cursor.getString(cursor.getColumnIndex("contact_name")) == null) viewHolder.contactName.setText(cursor.getString(cursor.getColumnIndex("contact_number"))); else viewHolder.contactName.setText(cursor.getString(cursor.getColumnIndex("contact_name"))); // Set the duration to the view viewHolder.duration.setText(Utils.convertTime(Integer.parseInt(cursor.getString(cursor.getColumnIndex("duration_sum"))))); // Set the tags to the view to be used later when the user click the group view view.setTag(R.id.contact_number, cursor.getString(cursor.getColumnIndex("contact_number"))); view.setTag(R.id.contact_name, cursor.getString(cursor.getColumnIndex("contact_id"))); if(!currentContactCursor.isClosed()) currentContactCursor.close(); } } @Override protected void bindChildView(View view, Context context, Cursor cursor, boolean expanded) { try { if(cursor.getString(cursor.getColumnIndex("contact_name")) == null) { mContactNameTextView = (TextView) view.findViewById(R.id.contact_name); mContactNameTextView.setText(cursor.getString(cursor.getColumnIndex("phone_number"))); } else { mContactNumberTextView = (TextView) view.findViewById(R.id.phone_number); mContactNumberTextView.setText(cursor.getString(cursor.getColumnIndex("contact_number"))); } mDurationTextView = (TextView) view.findViewById(R.id.duration); mDurationTextView.setText(cursor.getString(cursor.getColumnIndex("duration"))); } catch(Exception e) { e.printStackTrace(); } finally { if(cursor.isClosed()) cursor.close(); } } }
Trayectoria de pila completa
07-22 16:47:46.388: E/AndroidRuntime(7718): java.lang.IllegalStateException: Couldn t read row 1, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.database.CursorWindow.nativeGetLong(Native Method) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.database.CursorWindow.getLong(CursorWindow.java:515) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.widget.CursorTreeAdapter$MyCursorHelper.getId(CursorTreeAdapter.java:436) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.widget.CursorTreeAdapter.getChildId(CursorTreeAdapter.java:173) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.widget.ExpandableListConnector.getItemId(ExpandableListConnector.java:427) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.widget.AdapterView.getItemIdAtPosition(AdapterView.java:756) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.widget.AdapterView.setSelectedPositionInt(AdapterView.java:1128) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3147) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.View.dispatchTouchEvent(View.java:5541) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1951) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) 07-22 16:47:46.388: E/AndroidRuntime(7718): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1912) 07-22 16:47:46.388: E/AndroidRuntime(7718): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.app.Activity.dispatchTouchEvent(Activity.java:2364) 07-22 16:47:46.388: E/AndroidRuntime(7718): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1860) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.View.dispatchPointerEvent(View.java:5721) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2890) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2466) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2475) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.os.Handler.dispatchMessage(Handler.java:99) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.os.Looper.loop(Looper.java:137) 07-22 16:47:46.388: E/AndroidRuntime(7718): at android.app.ActivityThread.main(ActivityThread.java:4424) 07-22 16:47:46.388: E/AndroidRuntime(7718): at java.lang.reflect.Method.invokeNative(Native Method) 07-22 16:47:46.388: E/AndroidRuntime(7718): at java.lang.reflect.Method.invoke(Method.java:511) 07-22 16:47:46.388: E/AndroidRuntime(7718): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 07-22 16:47:46.388: E/AndroidRuntime(7718): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 07-22 16:47:46.388: E/AndroidRuntime(7718): at dalvik.system.NativeStart.main(Native Method)
- Establecer bordes para un elemento de grupo expandido mediante ExpandableListView
- ¿Cómo mostrar más de 3 niveles de Vista de lista expandible?
- GridView dentro de la lista expandible en android
- Android ExpandableListView y base de datos SQLite
- ¿Cómo puedo replicar este patrón de interfaz de usuario: haga clic en el elemento ListView y expanda debajo de él?
- ExpandableListView groupView checkbox unticking otras vistas de grupo
- Android: ¿Hay una manera de animar tanto el grupo como el listview de un ExpandableListView?
- Clear ExpandableListView
Como @Jens mencionó en el comentario:
¿Busca un identificador de fila (es decir, BaseColumns # _ID) y no lo encuentra en el cursor? ¿Qué columnas está utilizando en mContactsCursor – no ha olvidado el ID de fila en eso?
En todas las consultas, se debe especificar la columna _id
. Esto es lo que estaba causando el error, después de añadir la columna _id
a la consulta, funcionó.
Podríamos incluso obtener este error, incluso si tenemos _ID. Esto ocurre si hemos dado un field_name incorrecto en la consulta o pasando el field_name en la intención o donde se usa.
Si utiliza ContentProvider
para consultar, necesita agregar al menos _id a PROJECTION