简体   繁体   English

从SQLite数据库Android填充微调器

[英]Populating Spinner From SQLite Database Android

I'm attempting to make a dynamic drop down that will be filled by a SQLite table. 我正在尝试创建一个由SQLite表填充的动态下拉列表。 I have a Cursor object which I can pull the data I need from. 我有一个Cursor对象,我可以从中提取所需的数据。 I've been able to accomplish loading the values into the drop down with the code below: 我已经能够使用下面的代码将值加载到下拉列表中:

Spinner s = (Spinner) findViewById(R.id.spinner);
    ArrayAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    s.setAdapter(adapter);

    try{
        Cursor cursor = getAccounts();
        int accountnameIndex = cursor.getColumnIndexOrThrow(ACCOUNT_NAME);
        if(cursor.moveToFirst()){
            do{
                adapter.add(cursor.getString(accountnameIndex));
            } while(cursor.moveToNext());
        }
    } finally {
        MintLink.close();
    }

My problem is that I need the a selection from the drop down to also contain the RowID of the item selected. 我的问题是我需要从下拉列表中选择一个也包含所选项目的RowID。 I need to be able to select one item and have access to the value of that item in the back end. 我需要能够选择一个项目并且可以访问后端中该项目的值。 For example, think of a drop down in HTML. 例如,想一想HTML中的下拉菜单。 Each drop down selection has it's own hidden value that is pulled. 每个下拉选项都有自己的隐藏值。 I need this value to be hidden for me to allow me to know which ID they choose. 我需要隐藏此值才能让我知道他们选择了哪个ID。

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. 答案确实是使用SimpleCursorAdapter处理字符串列表,但也对匹配的ID字段进行特殊处理,该字段在选择行时返回。 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". 1)创建光标时,请确保查询返回标题为“_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. 2)创建SimpleCursorAdapter时,需要提供将放置行文本的TextView布局ID。 If using the android supplied layout android.R.layout.simple_spinner_item the text id you need to use is android.R.id.text1. 如果使用android提供的布局android.R.layout.simple_spinner_item,则需要使用的文本ID是android.R.id.text1。

Main.xml 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) {}
        });
    }
}

尝试使用SimpleCursorAdapter而不是手动将所有数据复制到ArrayAdapter

Here's another answer with loaders and cursors. 这是加载器和游标的另一个答案。

In the activity/fragment creation (said fragment/activity must implement LoaderManager.LoaderCallbacks<Cursor> ): 在活动/片段创建中(所述片段/活动必须实现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 不使用已弃用的API
  • use of the loader API 使用加载器API
  • customized adapter / layouts 定制的适配器/布局
  • view recycling 查看回收
  • API level 4 backward compatible (through support lib) API级别4向后兼容(通过支持lib)
  • background thread data loading 后台线程数据加载

Example of data binding can be found here. 可以在此处找到数据绑定的示例。

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

check "Filling the Layout with Data" section for usage of SimpleCursorAdapter 选中“使用数据填充布局”部分以使用SimpleCursorAdapter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM