Search code examples
androidcursorandroid-alertdialogsimplecursoradapterandroid-context

Custom SimpleCursorAdapter - refresh, update DB


My issue today is related to a custom SimpleCursorAdapter I've implemented. Here are my activities onCreate() and the custom SimpleCursorAdapter :

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    customSharedPreference = getSharedPreferences("myCustomSharedPrefs", Activity.MODE_PRIVATE);
    editor = customSharedPreference.edit();

    setContentView(R.layout.activity_1);
    op = new OperationsClass(getApplicationContext());
    op.open();

    Cursor cursor = op.getList();
    startManagingCursor(cursor);

    String[] columns = new String[] { "AAA", "BBB", "CCC"};
    int[] to = new int[] { R.id.entry_aaa,R.id.entry_bbb, R.id.entry_ccc};

    MyCursorAdapter mAdapter = new MyCursorAdapter(this, R.layout.custom_entry, cursor, columns, to);

    this.setListAdapter(mAdapter);

    op.close();
}

OperationsClass manages a database and the getList() function returns a cursor of the entries.

public class MyCursorAdapter extends SimpleCursorAdapter{

        private Context context;
        private MyCursorAdapter here = this;

        private int layout;

        public MyCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
            super(context, layout, c, from, to);
            this.context = context;
            this.layout = layout;
        }

        @Override
        public View newView(final Context context, Cursor cursor, ViewGroup parent) {

            Cursor c = getCursor();

            final LayoutInflater inflater = LayoutInflater.from(context);
            View v = inflater.inflate(layout, parent, false);

            int col1 = c.getColumnIndex("aaa");
            String name1 = c.getString(col1 );
            int col2 = c.getColumnIndex("bbb");
            String name2 = c.getString(col2 );
            int col3 = c.getColumnIndex("ccc");
            int name3 = c.getInt(col3 );

            final TextView text1 = (TextView) v.findViewById(R.id.entry_aaa);
            final TextView text2 = (TextView) v.findViewById(R.id.entry_bbb);
            final TextView text3 = (TextView) v.findViewById(R.id.entry_ccc);

            text1.setText(name);
            text2.setText(name2);

            if (name3 == 0)
                text3.setText("Not checked");
            else {
                text3.setText("Checked");
                text3.setOnClickListener(new View.OnClickListener()
                    {
                        public void onClick(View view)
                        {
                        text3.setText("Not checked");
                            // Here I would like to update my DB using
                            // OperationsClass and the SharedPrefs,
                            // and refresh the ListView with the new
                            // text value.
                        }
                    });
                }
            }
            return v;
        }

        @Override
        public void bindView(View v, final Context context, Cursor c) {
            // Same operations as higher
        }
}

Basically what I want to achieve is to refresh the ListView when the users clicks on the third column, which means its value changes (has been clicked or has not been). In the same time I wish to update the DB and the SharedPreferences(I could create a new object of both classes and recover from the application context, but that seems pretty heavy).


I also wish to know if there is a way to trigger one of the implemented methods in one activity when an AlertDialog has been opened (in the same app, I actually want to add an element to my database through an AlertDialog and make the Activity that popped it up retrieve a new cursor and refresh its List).


Solution

  • Basically what I want to achieve is to refresh the ListView when the users clicks on the 3rd column, which means its value changes (has been clicked or has not been). In the same time I wish to update the DB and the SharedPrefereces (I could create a new object of both classes and recover from the application context, but that seems pretty heavy).

    First of all, you shouldn't be implementing that logic in the newView method because that method will not be called for every row due to the recycling. The newView should be used only to build a new row view and nothing more. Use the bindView method for any row logic.

    Regarding the code in the onClick method I don't see where do you have problems. Update the database based on your logic and then query again the database for a Cursor with the new data and then use swapCursor() to update the adapter with the new values. This should work but it's not the recommended way mainly because you're doing every database operation on the main UI thread. Don't use the startManagingCursor method because this method runs the queries on the main UI thread, instead have a look at implementing a Loader in your activity to load data off the main UI thread. With a Loader you'll update the database values and then simply restart the Loader to update the list.

    I also wish to know if there is a way to trigger one of the implemented methods in one activity when an AlertDialog has been opened (in the same app, I actually want to add an element to my database through an AlertDialog and make the Activity that poped it up retrieve a new cursor and refresh its List).

    You're not saying anything about how you show that AlertDialog. If you want to update the list after you add the new element then use the listeners for the AlertDialog's buttons and the same code as above.