无法使用光标从数据库中成功检索Spinner选定的项目文本以填充我的应用程序中的联系人列表项目
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法使用光标从数据库中成功检索Spinner选定的项目文本以填充我的应用程序中的联系人列表项目相关的知识,希望对你有一定的参考价值。
我的应用程序有一个献血者的注册屏幕,血型字段是一个微调器。我将所有捐赠者信息保存在SQLite数据库中。现在我需要检索它并显示一个列表,显示所有已注册的献血者的血型。
我怎样才能做到这一点?
我在下面附上了我的所有代码。主要问题出现在RegisterActivity.java和DonorList.java中。
register activity.Java
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
public class RegisterActivity extends AppCompatActivity {
EditText edtname, edtnumber;
Spinner spblood;
Button btnregister, btnlist;
public static SQLiteHelper sqLiteHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
Spinner spinner = findViewById(R.id.blood_selector);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
sqLiteHelper = new SQLiteHelper(this, "Donors.sqlite", null, 1);
sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)");
btnregister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
Don or list.Java
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Spinner;
import java.util.ArrayList;
public class DonorList extends AppCompatActivity {
ListView listView;
ArrayList<Donor> list;
DonorListAdapter adapter = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.activity_main, list);
listView.setAdapter(adapter);
Cursor cursor = RegisterActivity.sqLiteHelper.getData("SELECT * FROM DONORS");
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
donor.Java
import android.widget.Spinner;
public class Donor {
private String name;
private String number;
private Spinner blood;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Spinner getBlood() {
return blood;
}
public void setBlood(Spinner blood) {
this.blood = blood;
}
public Donor(String name, String number, Spinner blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
SQLite helper.Java
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.widget.Spinner;
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public void queryData(String sql) {
SQLiteDatabase database = getWritableDatabase();
database.execSQL(sql);
}
public void insertData(String name, String number, Spinner blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood.getSelectedItem().toString());
statement.executeInsert();
}
public Cursor getData(String sql) {
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
Don or list adapter.Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class DonorListAdapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
@Override
public int getCount() {
return donorList.size();
}
@Override
public Object getItem(int position) {
return donorList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = new ViewHolder();
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
row = inflater.inflate(layout, null);
}
if (row != null) {
holder.txtname = row.findViewById(R.id.name_input);
}
if (row != null) {
holder.txtnumber = row.findViewById(R.id.numberinput);
}
if (row != null) {
holder.txtblood = (TextView) row.findViewById(R.id.blood_selector);
}
if (row != null) {
row.setTag(holder);
}
}
else {
holder = (ViewHolder) row.getTag();
}
Donor donor = donorList.get(position);
holder.txtname.setText(donor.getName());
holder.txtnumber.setText(donor.getNumber());
holder.txtblood.setText(donor.getBlood().toString());
return row;
}
}
activity_main.xml中
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lumen.dayem.blooddonor.MainActivity">
<ListView
android:id="@+id/contacts_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
activity_register.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/name_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/person_name"
android:ems="10"
android:inputType="textCapWords"
android:layout_marginBottom="5sp" />
<EditText
android:id="@+id/numberinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint"
android:ems="10"
android:inputType="phone"
android:layout_marginBottom="5sp" />
<TextView
android:id="@+id/blood"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/blood_type"
android:layout_marginBottom="10sp"/>
<Spinner
android:id="@+id/blood_selector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/blood_type"
android:prompt="@string/blood_select"
android:layout_marginBottom="5sp"/>
<Button
android:id="@+id/register_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/register" />
<Button
android:id="@+id/list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/show_donors" />
</LinearLayout>
contact_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/contact_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/contact_name"
android:textSize="22sp"/>
<TextView
android:id="@+id/contact_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceSmall"
android:text="@string/contact_number"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="29sp"
android:layout_marginStart="29sp"
android:layout_marginTop="31sp" />
<TextView
android:id="@+id/contact_blood"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceMedium"
android:text="@string/blood_type"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="300sp"
android:layout_marginStart="300sp"
android:layout_marginTop="30sp"/>
</RelativeLayout>
你的班级Donor
似乎有Spinner
类型的野战血。我将类型更改为String
,因为数据类不应包含任何View
s:
public class Donor
{
private String name;
private String number;
private String blood;
// Getters and Setters here...
public Donor(String name, String number, String blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
SQLiteHelper
应该有一个静态getInstance()
方法,所以你可以避免将它作为RegisterActivity
中的静态场。另外,我认为应该封装数据库设置。 Activity
不需要了解有关数据库实现的任何信息。所以我把DDL移到了SQLiteHelper
的onCreate()
并放弃了queryData()
。出于同样的原因,我将getData(String sql)
改为getDonors()
。最后,insertData()
应该将数据作为参数而不是View
s。因此,不应该传递Spinner
而是传递所选项目的值。
我的SQLiteHelper.java版本:
public class SQLiteHelper extends SQLiteOpenHelper{
private static SQLiteHelper sqliteHelper;
private static String dbName = "Donors.sqlite";
private static int version = 1;
private static final String CREATE_TABLE_DONORS = "CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)";
/**
* We use the application Context under the hood because this helps to avoid Exceptions
* @param ctx
*/
private SQLiteHelper(Context ctx){
super(ctx.getApplicationContext(), dbName, null, version);
}
/**
* SQLiteHelper as a Singleton
* @param ctx any Context
* @return x
*/
public static SQLiteHelper getInstance(Context ctx)
{
if(sqliteHelper == null){
sqliteHelper = new SQLiteHelper(ctx);
}
return sqliteHelper;
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_DONORS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// necessary if you have a new database version
}
public void insertData(String name, String number, String blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood);
statement.executeInsert();
}
public Cursor getDonors() {
String sql = "SELECT * FROM DONORS";
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
更新的RegisterActivity.java(注意我摆脱了局部变量微调器并且只使用了spblood):
public class RegisterActivity extends AppCompatActivity
{
private EditText edtname, edtnumber;
private Spinner spblood;
private Button btnregister, btnlist;
private SQLiteHelper sqLiteHelper;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spblood.setAdapter(adapter);
sqLiteHelper = SQLiteHelper.getInstance(this);
btnregister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood.getSelectedItem().toString()
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
DonorList
和适配器的变化是由于我对SQLiteHelper
和Donor
所做的更改。除此之外,您还需要将列表行的资源ID传递给Adapter的构造函数,而不是Activity的布局的资源ID。同样,列表行中TextView
s的R.id ....值必须与contact_item.xml中的值相匹配
Don or list.Java
public class DonorList extends AppCompatActivity
{
private ListView listView;
private ArrayList<Donor> list;
private DonorListAdapter adapter = null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.contact_item, list);
listView.setAdapter(adapter);
Cursor cursor = SQLiteHelper.getInstance(this).getDonors();
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
最后,适配器:
public class DonorListAdapter extends BaseAdapter
{
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
@Override
public int getCount() {
return donorList.size();
}
@Override
public Object getItem(int position) {
return donorList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
ViewHolder holder = new ViewHolder();
row = LayoutInflater.from(context).inflate(layout, null);
holder.txtname = (TextView)row.findViewById(R.id.contact_name);
holder.txtnumber = (TextView)row.findViewById(R.id.contact_number);
holder.txtblood = (TextView) row.findViewById(R.id.contact_blood);
row.setTag(holder);
}
ViewHolder viewHolder = (ViewHolder) row.getTag();
Donor donor = donorList.get(position);
viewHolder.txtname.setText(donor.getName());
viewHolder.txtnumber.setText(donor.getNumber());
viewHolder.txtblood.setText(donor.getBlood());
return row;
}
}
请享用!
以上是关于无法使用光标从数据库中成功检索Spinner选定的项目文本以填充我的应用程序中的联系人列表项目的主要内容,如果未能解决你的问题,请参考以下文章
R Shiny - 我无法从selectInput操作中检索选定的输出值