无法使用光标从数据库中成功检索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,因为数据类不应包含任何Views:

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移到了SQLiteHelperonCreate()并放弃了queryData()。出于同样的原因,我将getData(String sql)改为getDonors()。最后,insertData()应该将数据作为参数而不是Views。因此,不应该传递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和适配器的变化是由于我对SQLiteHelperDonor所做的更改。除此之外,您还需要将列表行的资源ID传递给Adapter的构造函数,而不是Activity的布局的资源ID。同样,列表行中TextViews的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操作中检索选定的输出值

从 Excel 的下拉列表中检索选定的值(在 C# 中创建)

在 oracle JPA () 中检索光标

无法从 Spinner 中选择项目

如何从 DataTables 中的选定数据中获取数据