Populating Spinner From SQLite Database Android

后端 未结 4 462
灰色年华
灰色年华 2020-11-30 08:35

I\'m attempting to make a dynamic drop down that will be filled by a SQLite table. I have a Cursor object which I can pull the data I need from. I\'ve been able to accompl

相关标签:
4条回答
  • 2020-11-30 08:43

    Example of data binding can be found here.

    http://developer.android.com/guide/topics/ui/binding.html

    check "Filling the Layout with Data" section for usage of SimpleCursorAdapter

    0 讨论(0)
  • 2020-11-30 08:44

    Try using a SimpleCursorAdapter instead of copying all the data by hand into an ArrayAdapter.

    0 讨论(0)
  • 2020-11-30 08:54

    This is an old question but the first one I found when figuring out this issue. Here is a detailed explanation with full source which may cut some legwork.

    The answer is indeed to use a SimpleCursorAdapter which handles a list of strings but also has special handling for a matched ID field that gets returned when a row is selected. The key to making this work is to know the two following obscure bits of information:

    1) When creating the cursor make sure the query returns a field titled "_id". This field need not be displayed anywhere but it's value will be passed back when a list item is selected.

    2) When creating a SimpleCursorAdapter you need to supply the TextView layout IDs where the row text will be placed. If using the android supplied layout android.R.layout.simple_spinner_item the text id you need to use is android.R.id.text1.

    Main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <Spinner
            android:id="@+id/spinner1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            ></Spinner>
    </RelativeLayout>
    

    Activity code:

    public class TesterActivity extends Activity {
    public Context mContext;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        // just for this example:
        // create database table with an id field and a text field and add some data
        class MyDBHelper extends SQLiteOpenHelper {
            public MyDBHelper(Context context) {
                super(context, "someDB", null, 2);
            }
            @Override
            public void onCreate(SQLiteDatabase db) {
                db.execSQL("CREATE TABLE someTable (someIDF INTEGER, someTextF TEXT)");
            }
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                db.execSQL("DROP TABLE IF EXISTS someTable");
                onCreate(db);
                db.execSQL("INSERT INTO someTable (someIDF, someTextF) VALUES (54, 'Some text')");
                db.execSQL("INSERT INTO someTable (someIDF, someTextF) VALUES (99, 'Some more text')");
                db.execSQL("INSERT INTO someTable (someIDF, someTextF) VALUES (173, 'Even more text')");
            }
        }
        SQLiteDatabase db = new MyDBHelper(this).getWritableDatabase();
    
        // get a cursor from the database with an "_id" field
        Cursor c = db.rawQuery("SELECT someIDF AS _id, someTextF FROM someTable", null);
    
        // make an adapter from the cursor
        String[] from = new String[] {"someTextF"};
        int[] to = new int[] {android.R.id.text1};
        SimpleCursorAdapter sca = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, c, from, to);
    
        // set layout for activated adapter
        sca.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
    
        // get xml file spinner and set adapter 
        Spinner spin = (Spinner) this.findViewById(R.id.spinner1);
        spin.setAdapter(sca);
    
        // set spinner listener to display the selected item id
        mContext = this;
        spin.setOnItemSelectedListener(new OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id){
                Toast.makeText(mContext, "Selected ID=" + id, Toast.LENGTH_LONG).show();
            }
            public void onNothingSelected(AdapterView<?> parent) {}
            });
        }
    }
    
    0 讨论(0)
  • 2020-11-30 09:04

    Here's another answer with loaders and cursors.

    In the activity/fragment creation (said fragment/activity must implement LoaderManager.LoaderCallbacks<Cursor>):

    final Spinner spinner = (Spinner) findViewById(R.id.spinner);
    mAdapter = new MyCursorAdapter(getActivity());
    spinner.setAdapter(mAdapter);
    getLoaderManager().initLoader(SOME_INT_CONSTANT, null, this);
    

    In your activity/fragment:

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new MyCursorLoader(getActivity(), args);
    }
    
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        mAdapter.swapCursor(data);
    }
    
    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }
    

    Here's the cursor adapter:

    class MyCursorAdapter extends CursorAdapter {
        class ViewsHolder {
            TextView text1, text2;
        }
    
        public MyCursorAdapter(Context context, Bundle args) {
            super(context, null, false);
            // do something with args
        }
    
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View v = LayoutInflater.from(context).inflate(R.layout.your_item_layout, parent, false);
            ViewsHolder holder = new ViewsHolder();
            holder.text1 = (TextView) v.findViewById(R.id.text1);
            holder.text2 = (TextView) v.findViewById(R.id.text2);
            v.setTag(holder);
            return v;
        }
    
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            ViewsHolder holder = (ViewsHolder) view.getTag();
            String text1 = cursor.getString(cursor.getColumnIndex(KEY_TEXT1));
            String text2 = cursor.getString(cursor.getColumnIndex(KEY_TEXT2));
            holder.text1.setText(text1);
            holder.text2.setText(text2);
        }
    }
    

    Here's the cursor loader:

    public class MyCursorLoader extends CursorLoader {
        private final YourSQLiteDbAdapter mHelper;
    
        public MyCursorLoader(Context context) {
            super(context);
            mHelper = new YourSQLiteDbAdapter(context);
            mHelper.openReadOnly();
        }
    
        @Override
        public Cursor loadInBackground() {
            return mHelper.selectYourDataAsACursor();
        }
    
        @Override
        protected void onStopLoading() {
            super.onStopLoading();
            mHelper.close();
        }
    }
    

    Using this you get:

    • no use of deprecated APIs
    • use of the loader API
    • customized adapter / layouts
    • view recycling
    • API level 4 backward compatible (through support lib)
    • background thread data loading
    0 讨论(0)
提交回复
热议问题