无法使用光标从数据库中成功检索Spinner选定的项目文本以填充我的应用程序中的联系人列表项目

问题描述 投票:0回答:1

我的应用程序有一个献血者的注册屏幕,血型字段是一个微调器。我将所有捐赠者信息保存在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>
java android sqlite cursor spinner
1个回答
1
投票

你的班级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;
    }
}

请享用!

© www.soinside.com 2019 - 2024. All rights reserved.