androidspinnermatrixcursor

How to implement a MatrixCursor for a Spinner?


I have a SQLite query that returns a Cursor. I want to add some extra rows to the Cursor by implementing a MatrixCursor(to try to keep the first item of real data from automatically selected when clicked). Then I want to map them to a SimpleCursorAdapter. I kept reading the posts(and codes) but still remain fuzzy to me how to code it to my existing code listed below.

    Cursor cursor = myDB.query(DATABASE_TABLE_NAME, resultColumns, whereClause,
            whereArgs, null, null, null, null);

    // Create Spinner View object from layout resource
    Spinner spinner = (Spinner) findViewById(R.id.spinner);

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            android.R.layout.simple_spinner_item, // Use a template
                                                  // that displays a
                                                  // text view
            cursor, // Give the cursor to the adapter
            new String[] {"ename"}, // Map the NAME column in the
                                                 // people database to...
            new int[] {android.R.id.text1}); 

    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
    spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());

Solution

  • If you want to build a MatrixCursor from a simple Cursor you'll have to parse the entire initial Cursor and append the rows you want:

    //...
        MatrixCursor mc = new MatrixCursor(resultColumns);
        // add extra rows, this will probably not work if you want to insert them
        // between the initial cursor rows because of the _id column that need autoincrement values
        mc.addRow(new Object[] { new Long(-2), "Extra name1" }); 
        mc.addRow(new Object[] { new Long(-1), "Extra name2" });
        // I don't know what your cursor holds, I assumed you have the _id column(long value)
        // and a name(String value)
        int size = cursor.getCount();
        for (int i = 0; i < size; i++) {
            cursor.moveToPosition(i);
                mc.addRow(new Object[] {
                cursor.getLong(cursor.getColumnIndex(/*the _id column*/)),
                cursor.getString(cursor.getColumnIndex(/* the name column(ename?!?)*/)) });
        }
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_spinner_item, mc, new String[] {"ename"}, new int[] {android.R.id.text1}); 
    //...
    

    If you're doing this just to avoid the OnItemSelectedListener from firing when the Spinner is shown, maybe you could have another approach. For example in your listener:

        //boolean status = true; flag in MyOnItemSelectedListener
    
        @Override
        public void onItemSelected(AdapterView<?> parent, View view,
                int position, long id) {
            if (status) {
                status = false;// this is the first listener trigger so you probably want to ignore it
                return;
            }
            // do stuff here
        }
    

    Note: I don't know how good is the above solution. If you look there are probably much better solution to this Spinner related issue.