ملء الدوار من قاعدة بيانات SQLite Android
سؤال
أحاول إنشاء انخفاض ديناميكي سيتم ملؤه بواسطة جدول SQLite. لدي كائن مؤشر يمكنني سحب البيانات التي أحتاج إليها. لقد تمكنت من تحقيق تحميل القيم في المنسدلة مع الكود أدناه:
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();
}
مشكلتي هي أنني بحاجة إلى تحديد من المنسدلة لاحتواء العنصر المحدد أيضًا. يجب أن أكون قادرًا على تحديد عنصر واحد والوصول إلى قيمة هذا العنصر في النهاية الخلفية. على سبيل المثال ، فكر في المنسدلة في HTML. يحتوي كل اختيار منسد لأسفل على قيمة خفية خاصة بها. أحتاج إلى إخفاء هذه القيمة بالنسبة لي للسماح لي بمعرفة المعرف الذي يختارونه.
المحلول
حاول استخدام SimpleCursorAdapter
بدلاً من نسخ جميع البيانات باليد إلى ArrayAdapter
.
نصائح أخرى
هذا سؤال قديم ولكن أول سؤال وجدته عند اكتشاف هذه المشكلة. فيما يلي تفسير مفصل مع المصدر الكامل الذي قد يقطع بعض العمل.
الجواب هو في الواقع استخدام SimpleCursorAdapter الذي يتولى قائمة من الأوتار ولكن لديه أيضًا معالجة خاصة لحقل معرف متطابق يتم إرجاعه عند تحديد صف. مفتاح جعل هذا العمل هو معرفة البتات الغامضة التالية من المعلومات:
1) عند إنشاء المؤشر ، تأكد من إرجاع الاستعلام حقلًا بعنوان "_id". لا يلزم عرض هذا الحقل في أي مكان ، ولكن سيتم تمرير القيمة عند تحديد عنصر قائمة.
2) عند إنشاء SimpleCursorAdapter ، تحتاج إلى توفير معرفات تخطيط TextView حيث سيتم وضع نص الصف. إذا كنت تستخدم نظام Android الذي تم توفيره Android.r.layout.simple_spinner_item فإن معرف النص الذي تحتاجه إلى استخدامه هو 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>
رمز النشاط:
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) {}
});
}
}
إليك إجابة أخرى مع اللوادر والمؤشرات.
في النشاط/إنشاء الشظية (يجب تنفيذ الشظية/النشاط المذكور 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);
في نشاطك/جزءك:
@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);
}
ها هو محول المؤشر:
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);
}
}
ها هو لوكور المؤشر:
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();
}
}
باستخدام هذا ستحصل عليه:
- لا استخدام واجهات برمجة التطبيقات المنخفضة
- استخدام واجهة برمجة تطبيقات اللودر
- محول / تخطيطات مخصصة
- عرض إعادة التدوير
- API المستوى 4 متوافق مع الخلف (من خلال دعم lib)
- تحميل بيانات موضوع الخلفية
مثال على ربط البيانات يمكن العثور عليها هنا.
http://developer.android.com/guide/topics/ui/Binding.html
تحقق من قسم "ملء التصميم مع البيانات" لاستخدام SimpleCursorAdapter