I use SimpleCursorAdapter to display data from a local database to a ListView with custom markup. That's how I create an adapter

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); 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, cursor, from, to); lv_products.setAdapter(adapter); 

I created an instance of the cursor, an array with the names of the columns in the database and with the identifiers of the View components from the custom markup. I give the created adapter to the list.

But the class of the adapter itself ...

 public class InteractiveArrayAdapter extends SimpleCursorAdapter { private int layout; public InteractiveArrayAdapter(Context _context, int _layout, Cursor _cursor, String[] _from, int[] _to) { super(_context, _layout, _cursor, _from, _to); layout = _layout; } @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(prod_complete==1); } @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; } } 

I manage checkboxes by clicking on the entire ListView item, in the listener I get the id of this record and with its help I make various queries to the database (delete, for example). As you can see above, I blocked the checkboxes, because all the work is already configured in the ListView listener, so please do not criticize it, everything works.

The problem is different. My database may contain data not from the same category, so I just do not need to display all the data from the table in a row. You need to implement a filter that will compare the number from one specially designed column with another number that came through put / getExtra from the previous activity and add the item to the list only if these numbers match. Otherwise, the filter will simply skip this line and move on to the next one.

What did I do? I made all the code in the bindView () method run only if this condition is true

  (_cursor.getInt(_cursor.getColumnIndex(DatabaseProductHelper.PRODUCT_LIST))==extra); 

The extra variable is the same number from the previous activity. Well, in general, by adding an if structure to this method, I was hoping for a fixed bug, but it turned out to be in vain. Instead of those items that should not exist at all (since they did not pass the extra check), empty items began to stand. Everything became clear. I do an extra check and in the case of validity, the code is executed to simply insert the data from the database into the TextView and CheckBox.

But how to make it so that at this check there are no items at all? Can their height be zero? : DDD Although, this is also not clear how to implement))

PROFIT! As the second argument in the query method, I changed null to the list = extra condition, thereby applying a filter to the cursor, which will take only data that has a number in the list column that is equal to the extra variable

UPD Now another rake :) When scrolling ListView checkboxes that left the screen, when you go back, lose the changes. How can I fix this?

  • And your question is that ... ??? - Vladyslav Matviienko
  • @metalurgus, rules. all - Flippy
  • Most likely you need to query the cursor already with the necessary filter using the database and SQL tools so that the cursor already contains only the necessary data, and not then try to filter something from the whole heap using code. This is how they work with the database, make up exact queries, what exactly should be obtained in the final table, but do not select the entire database and then filter out something from it. These five null at the end of the query() method is actually a powerful tool for filtering and sorting the database directly in the query, but you do not use them - pavlofff

1 answer 1

You need to get a Cursor with already prepared and filtered values ​​using the tools of the SQLite database itself and the SQL language, rather than selecting the entire table and then trying to filter something with the code, especially right in the adapter, this is absolutely not the right decision. The adapter should only display the data provided to it, and not process it.

SQL is a very powerful language and allows you to make ANY sample from the database with only the necessary data in the total returned table (in the returned cursor). That is, you need to use the SQL query to the database to get the final cursor only with the necessary values ​​and then transfer it to the adapter, which simply converts these values ​​to View for items.

This is how they work with the database - such requests are many times faster than the code then filters the cursor and in general this is the right approach.