从 SQLite 数据库 Android 填充 Spinner
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2196426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Populating Spinner From SQLite Database Android
提问by crv
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 accomplish loading the values into the drop down with the code below:
我正在尝试制作一个将由 SQLite 表填充的动态下拉列表。我有一个 Cursor 对象,我可以从中提取我需要的数据。我已经能够使用以下代码将值加载到下拉列表中:
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. 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. 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.
我的问题是我需要从下拉列表中进行选择以包含所选项目的 RowID。我需要能够选择一个项目并在后端访问该项目的值。例如,想想 HTML 中的下拉菜单。每个下拉选择都有它自己的隐藏值被拉出。我需要为我隐藏这个值,让我知道他们选择了哪个 ID。
采纳答案by CommonsWare
Try using a SimpleCursorAdapter
instead of copying all the data by hand into an ArrayAdapter
.
尝试使用 aSimpleCursorAdapter
而不是手动将所有数据复制到ArrayAdapter
.
回答by MindSpiker
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:
答案确实是使用 SimpleCursorAdapter 来处理字符串列表,但也对匹配的 ID 字段进行特殊处理,该字段在选择一行时返回。完成这项工作的关键是了解以下两个晦涩的信息:
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.
1) 创建游标时,请确保查询返回标题为“_id”的字段。该字段不需要在任何地方显示,但它的值将在选择列表项时传回。
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.
2) 创建 SimpleCursorAdapter 时,您需要提供放置行文本的 TextView 布局 ID。如果使用 android 提供的布局 android.R.layout.simple_spinner_item,则您需要使用的文本 ID 是 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) {}
});
}
}
回答by Benoit Duffez
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
- use of the loader API
- customized adapter / layouts
- view recycling
- API level 4 backward compatible (through support lib)
- background thread data loading
- 不使用已弃用的 API
- 加载器 API 的使用
- 定制的适配器/布局
- 查看回收
- API 级别 4 向后兼容(通过支持库)
- 后台线程数据加载
回答by Anji
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