Checkboxes when caring for a screen lose their positions when returning. Here - SimpleCursorAdapter - the filter for the cursor is all the code (my question). How to implement a method to save boolean values? Really, instead of a cursor in the adapter, I need to send an array of boolean values? And how to take data through the cursor in the bindView () method? After all, I will remove the cursor, but it is needed.

Method for receiving data from the database

private void getProductList() { String filter = "list=" + intValue; final Cursor cursor = mSqLiteDatabase.query("products", new String[] {DatabaseProductHelper.PRODUCT_ID, DatabaseProductHelper.PRODUCT_NAME, DatabaseProductHelper.PRODUCT_COUNT, DatabaseProductHelper.PRODUCT_LIST, DatabaseProductHelper.PRODUCT_TYPE, DatabaseProductHelper.PRODUCT_COMPLETE}, null, null, null, null, null) ; final Cursor cursorc = mSqLiteDatabase.query("products", new String[] {DatabaseProductHelper.PRODUCT_ID, DatabaseProductHelper.PRODUCT_NAME, DatabaseProductHelper.PRODUCT_COUNT, DatabaseProductHelper.PRODUCT_LIST, DatabaseProductHelper.PRODUCT_TYPE, DatabaseProductHelper.PRODUCT_COMPLETE}, filter, null, null, null, null) ; final ArrayList<String> arrTblNames = new ArrayList<String>(); if (cursor.moveToFirst()) { while ( !cursor.isAfterLast() ) { if(cursor.getInt(cursor.getColumnIndex("list"))==intValue) { arrTblNames.add(cursor.getString(cursor.getColumnIndex("name"))); } cursor.moveToNext(); } String[] from = {DatabaseProductHelper.PRODUCT_NAME, DatabaseProductHelper.PRODUCT_COUNT, DatabaseProductHelper.PRODUCT_TYPE, DatabaseProductHelper.PRODUCT_COMPLETE}; int[] to = {R.id.ColMemberID, R.id.ColName, R.id.count_tv, R.id.chb_products}; adapter = new InteractiveArrayAdapter(ListBuilder.this, R.layout.row, cursorc, from, to ); //lv_products.setAdapter(adapter); } if(!arrTblNames.isEmpty()){ empty_bd_layout.setAlpha(0); lv_products.setAdapter(adapter); } else{ empty_bd_layout.setAlpha(255); } } 

And the adapter itself

 public class InteractiveArrayAdapter extends SimpleCursorAdapter { private int layout; private boolean checked[]; public InteractiveArrayAdapter(Context _context, int _layout, Cursor _cursor, String[] _from, int[] _to) { super(_context, _layout, _cursor, _from, _to); layout = _layout; int counts = _cursor.getCount(); checked = new boolean[counts]; for (int i = 0; i < counts; i++){ int checkMarker = _cursor.getInt(_cursor.getColumnIndex("complete")); checked[i] = checkMarker == 1; } } @Override public void bindView(View view, Context _context, Cursor _cursor) { String prod_name = _cursor.getString(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_NAME)); String prod_count = _cursor.getString(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_COUNT)); String prod_type = _cursor.getString(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_TYPE)); // int prod_complete = _cursor.getInt(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_COMPLETE)); TextView name_prod_tv = (TextView)view.findViewById(R.id.ColMemberID); TextView count_prod_tv = (TextView)view.findViewById(R.id.ColName); TextView type_prod_tv = (TextView)view.findViewById(R.id.count_tv); CheckBox chb = (CheckBox)view.findViewById(R.id.chb_products); chb.setFocusable(false); chb.setClickable(false); name_prod_tv.setText(prod_name); count_prod_tv.setText(prod_count); type_prod_tv.setText(prod_type); chb.setChecked(checked[_cursor.getPosition()]); } @Override public View newView(Context _context, Cursor _cursor, ViewGroup _parent) { LayoutInflater inflater = (LayoutInflater)_context.getSystemService(_context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(layout, _parent, false); return view; } public void setChecked(int position){ // ΠΈΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΊΠ»ΠΈΠΊΠ° этим ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ checked[position]=!checked[position]; } } 

LogCat FATAL EXCEPTION: main 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime Process: ru.diskrim.listbuy, PID: 1468 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime java.lang.RuntimeException: Unable to start activity ComponentInfo {ru.diskrim.listbuy / ru.diskrim.listbuy.ListBuilder}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 4 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.app. ActivityThread.performLaunchActivity (ActivityThread.java:2325) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2387) 05-09 07: 18: 292929 1468 1468 E AndroidRuntime at android.app.ActivityThread.access $ 800 (ActivityThread.java:151) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1303) 05-09 07:18 : 29.529 1468 1468 E AndroidRuntime at android.os.Handler.dispatchMessage (Handler.java:102) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at androi d.os.Looper.loop (Looper.java:135) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.app.ActivityThread.main (ActivityThread.java 12.2525) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at java.lang.reflect.Method.invoke (Native Method) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at java.lang.reflect.Method.invoke (Method.javaUE72) 05-09 07 : 18: 29.529 1468 1468 E AndroidRuntime at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:902) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at com.android.internal.os. ZygoteInit.main (ZygoteInit.java:697) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at de.robv.android.xposed.XposedBridge.main (XposedBridge.java:117) 05-09 07: 18: 2929 1468 1468 E AndroidRuntime Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 4 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.database.AbstractCursor.checkPosition (AbstractCursor.java T26) 05 -09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.database.AbstractWindowedCursor.checkPosition (AbstractWindowedCursor.java:136) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.database.AbstractWindowedCursor.getInt (AbstractWindowedCursor.java:68) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at en.diskrim.listbuy.ListBuilder $ InteractiveArrayAdapter. (ListBuilder.java:245) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at en.diskrim.listbuy.ListBuilder.getProductList (ListBuilder.jr 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at en.diskrim.listbuy.ListBuilder.onCreate (ListBuilder.java:184) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.app.Activity.performCreate ( Activity.java:6033) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1106) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime at android.app. ActivityThread.performLaunchActivity (ActivityThread.java:2278) 05-09 07: 18: 29.529 1468 1468 E AndroidRuntime ... 11 more

  • recommend yet to learn the parameters of the method of query() / request should look something like this: final Cursor cursorc = mSqLiteDatabase.query("products", new String[] {DatabaseProductHelper.PRODUCT_ID, DatabaseProductHelper.PRODUCT_NAME, DatabaseProductHelper.PRODUCT_COUNT, DatabaseProductHelper.PRODUCT_LIST, DatabaseProductHelper.PRODUCT_TYPE, DatabaseProductHelper.PRODUCT_COMPLETE}, "list = ?", new String[] {""+ intValue], null, null, null) ; - pavlofff
  • @pavlofff, but what about the line boolean [] checked?) - Flippy

1 answer 1

The solution is not much different from this answer , with the difference that you need to handle clicks from the activation, and not the listener in the adapter.

Since we cannot change the values ​​in the cursor, but only read them from there, in order to memorize the current state of checkboxes, we need to create a local storage.

In the adapter you need to transfer the data that should be displayed in the widget, in your case it is a cursor with a selection from the database. Auxiliary array of Boolean values ​​is not required to be transferred anywhere; it is created inside the adapter.

An example implementation might look like this:

 private void getProductList() { // Если трСбуСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ имя, слСдуСт ΠΈ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΈΠ· Π‘Π” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ //ΠΊΠΎΠ»ΠΎΠ½ΠΊΡƒ с ΠΈΠΌΠ΅Π½Π΅ΠΌ, Π° Π½Π΅ всС Π² ΠΊΡƒΡ‡Ρƒ // Если трСбуСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ записи с ΠΊΠ°ΠΊΠΈΠΌ Ρ‚ΠΎ условиСм, Ρ‚ΠΎ ΠΈΡ… ΠΈ Π½Π°Π΄ΠΎ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ, // Π° Π½Π΅ всС Π² подряд, Π° ΠΏΠΎΡ‚ΠΎΠΌ Π²Ρ‹Π±ΠΈΡ€Π°Ρ‚ΡŒ Π½ΡƒΠΆΠ½Ρ‹Π΅ ΠΊΠ°ΠΊΠΈΠΌ Ρ‚ΠΎ Ρ†ΠΈΠΊΠ»ΠΎΠΌ // Ρ‚Π°ΠΊ ΠΆΠ΅ эти Π΄Π°Π½Π½Ρ‹Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ ΠΈ Π² курсор для Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° ΠΈ Π½Π΅Ρ‚ Π½ΡƒΠΆΠ΄Ρ‹ // ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Ρ‚ΠΎ ΠΆΠ΅ самоС Π΄Π²Π°ΠΆΠ΄Ρ‹ // final Cursor cursor = mSqLiteDatabase.query("products", new String[] {DatabaseProductHelper.PRODUCT_ID, DatabaseProductHelper.PRODUCT_NAME,"list = ?", new String[] {""+ intValue}, null, null, null) ; //Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΡƒΠΆΠ½Ρ‹Π΅ Π² Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π΅ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ final Cursor cursorc = mSqLiteDatabase.query("products", new String[] {DatabaseProductHelper.PRODUCT_ID,DatabaseProductHelper.PRODUCT_NAME, DatabaseProductHelper.PRODUCT_COUNT, DatabaseProductHelper.PRODUCT_TYPE, DatabaseProductHelper.PRODUCT_COMPLETE}, "list = ?", new String[] {""+ intValue}, null, null, null); final ArrayList<String> arrTblNames = new ArrayList<String>(); // ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· курсора Π² массив сильно упрощаСтся, // Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρƒ нас Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΡƒΠΆΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ while ( cursorc.moveToNext() ) { arrTblNames.add(cursorc.getString(cursorc.getColumnIndex("name"))); } String[] from = {DatabaseProductHelper.PRODUCT_NAME, DatabaseProductHelper.PRODUCT_COUNT, DatabaseProductHelper.PRODUCT_TYPE, DatabaseProductHelper.PRODUCT_COMPLETE}; int[] to = {R.id.ColMemberID, R.id.ColName, R.id.count_tv, R.id.chb_products}; adapter = new InteractiveArrayAdapter(ListBuilder.this, R.layout.row, cursorc, from, to ); //lv_products.setAdapter(adapter); } // Ρƒ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠ² Π΅ΡΡ‚ΡŒ свойство Visiblity, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ управляСт Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒΡŽ Π½Π° // экранС, Π·Π°Ρ‡Π΅ΠΌ Ρ‚ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ ? // я Π±Ρ‹ помСнял всю Π»ΠΎΠ³ΠΈΠΊΡƒ Π²ΠΎΠΎΠ±Ρ‰Π΅, исходя ΠΈΠ· условия Π½ΠΈΠΆΠ΅, // Π·Π°Ρ‡Π΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π°nь ΠΈ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, Ссли ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π½Π΅ понадобится if(!arrTblNames.isEmpty()){ empty_bd_layout.setAlpha(0); lv_products.setAdapter(adapter); } else{ empty_bd_layout.setAlpha(255); } } 

adapter:

 public class InteractiveArrayAdapter extends SimpleCursorAdapter { private int layout; private boolean checked[]; public InteractiveArrayAdapter(Context _context, int _layout, Cursor _cursor, String[] _from, int[] _to) { super(_context, _layout, _cursor, _from, _to); layout = _layout; // ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ массив Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ чСкбоксов ΠΈΠ· курсора checked = new boolean[_cursor.getCount()]; int i = 0; while ( _cursor.moveToNext() ) { int checkMarker = _cursor.getInt(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_COMPLETE)); checked[i] = (checkMarker == 1) ? true: false; i = i + 1; } // Π½ΡƒΠΆΠ½ΠΎ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ курсора Π² ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ // ΠΏΠ΅Ρ€Π΅Π΄ ΠΏΠ΅Ρ€Π²ΠΎΠΉ записью, для ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° _cursor.moveToPosition(-1); } @Override public void bindView(View view, Context _context, Cursor _cursor) { String prod_name = _cursor.getString(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_NAME)); String prod_count = _cursor.getString(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_COUNT)); String prod_type = _cursor.getString(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_TYPE)); // эта строка здСсь Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠΎ Π²ΠΈΠ΄ΠΈΠΌΠΎΠΌΡƒ Π½Π΅ Π½ΡƒΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ значСния ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΎΠΊ // ΠΈΠ· курсора ΠΌΡ‹ ΡƒΠΆΠ΅ ΠΈΠ·Π²Π»Π΅ΠΊΠ»ΠΈ //int prod_complete = _cursor.getInt(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_COMPLETE)); TextView name_prod_tv = (TextView)view.findViewById(R.id.ColMemberID); TextView count_prod_tv = (TextView)view.findViewById(R.id.ColName); TextView type_prod_tv = (TextView)view.findViewById(R.id.count_tv); CheckBox chb = (CheckBox)view.findViewById(R.id.chb_products); chb.setFocusable(false); chb.setClickable(false); name_prod_tv.setText(prod_name); count_prod_tv.setText(prod_count); type_prod_tv.setText(prod_type); // устанавливаСм чСкбоксы ΠΏΠΎ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌΡƒ массиву, Π° Π½Π΅ ΠΏΠΎ курсору // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ курсора (ΠΈ соотвСтствСнно Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π°) Ρ‡Π΅Ρ€Π΅Π· Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ chb.setChecked(checked[_cursor.getPosition()]); } @Override public View newView(Context _context, Cursor _cursor, ViewGroup _parent) { LayoutInflater inflater = (LayoutInflater)_context.getSystemService(_context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(layout, _parent, false); return view; } // ΠΌΠ΅Ρ‚ΠΎΠ΄ для фиксации ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΎΠΊ чСкбоксов ΠΈΠ· Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ‚ΠΈ public void setChecked(int position){ // ΠΈΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΊΠ»ΠΈΠΊΠ° этим ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ checked[position] = !checked[position]; } } 

As I recall, you record changes to the database by checkbox marks when processing a click in the list listener, so this action is not included in the adapter, but it must be present, otherwise the marks will be lost when leaving the list.

  • now I understand everything is average) that's just a mistake. in LogCat-E android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 2 ... swears at the line int checkMarker = _cursor.getInt (_cursor.getColumnIndex ("complete")); PS when instead of the hard column name there was a reference to a variable from the wrapper class, it produced the same error - Flippy
  • it says out of range. The getColumnIndex() method returns -1, and for arrays indexes are possible starting from zero. The reason itself is that there is no column in the cursor to which you refer, in this case -1 is returned, and not the column number. Most likely the name of the column in the request is incorrectly written. - pavlofff
  • No, the column name in the request is correct - Flippy
  • and yet, the getColumnIndex() method cannot find a column with the specified name. if the name is spelled correctly, including capital letters, possible spaces at the beginning / end, or other confusions with symbols, then the received cursor does not have this column at all, see the query that you send to get the cursor. - pavlofff
  • Try to put just the number of this column (counting starts from zero). For example, if this column is the fourth in the table, then: int checkMarker = _cursor.getInt(3); However, the very fact that the cursor size in the spectra is indicated in three columns (with a size of 2 - columns 0,1,2) suggests the absence of the cursor you need in the received cursor, see your request and the inclusion of this column in the sample. - pavlofff