使用简单的游标适配器使用 SQLite 数据库填充 listView

Populating a listView with SQLite database using simple cursor adapter

我有一个包含 3 列和一个 ListView 的 SQLite 数据库。我想用 SQLite 填充 listView。我认为我的编码是正确的,但是当我想查看 listView 时我的应用程序崩溃了。 下面是我的示例代码:

MainActivity.java

public class MainActivity extends ActionBarActivity {
Registration register;
EditText name, grade;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    name = (EditText) findViewById(R.id.editName);
    grade = (EditText) findViewById(R.id.editGrade);
    register = new Registration(this);
        }

public void addButton(View view) {
    String eName = name.getText().toString();
    String eGrade = grade.getText().toString();
    register.insert(eName, eGrade);
    name.setText("");
    grade.setText("");
    Toast.makeText(this, "Item added", Toast.LENGTH_SHORT).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }
    if (id == R.id.sqlView) {
        Intent intent = new Intent(this, ViewDatabase.class);
        startActivity(intent);
    }

    return super.onOptionsItemSelected(item);
}}

sqlOpenHelper.java

public class sqlOpenHelper extends SQLiteOpenHelper{

public static final String DATABASE_NAME = "FirstBase.db";
public static final String TABLE_NAME = "First_table";
public static final int VERSION = 1;
public static final String C_KEY_ID = "ID";
public static final String C_name = "Name";
public static final String C_grade = "Grade";
public static final String SCRIPT = "CREATE TABLE " + TABLE_NAME + " ( " +
        C_KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
        C_name + " TEXT NOT NULL, " +
        C_grade + " TEXT NOT NULL " + ");";



public sqlOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
    super(context, name, factory, version);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL(SCRIPT);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    String DELETE_SCRIPT = "DROP TABLE IF EXISTS " + TABLE_NAME;
    db.execSQL(DELETE_SCRIPT);
    onCreate(db);
}}

Registration.java

  public class Registration {
   SQLiteDatabase db;
   sqlOpenHelper oh;
   Context context;

public Registration(Context context) {
    this.context = context;
}


public Cursor print() {
    oh = new sqlOpenHelper(context, oh.DATABASE_NAME, null, oh.VERSION);
    String[] columns = {oh.C_KEY_ID, oh.C_name, oh.C_grade};
    db = oh.getWritableDatabase();
    Cursor cursor = db.query(sqlOpenHelper.TABLE_NAME, columns, null, null, null, null, null);
    return cursor;

}
public void insert(String name, String grade) {
    ContentValues values = new ContentValues();
    values.put(oh.C_name, name);
    values.put(oh.C_grade, grade);
    oh = new sqlOpenHelper(context, oh.DATABASE_NAME, null, oh.VERSION);
    db = oh.getWritableDatabase();
    db.insert(oh.TABLE_NAME, null, values);
    db.close();
}}

ViewDatabase.java

public class ViewDatabase extends ActionBarActivity {

private static final String[] from = new String[] {
        sqlOpenHelper.C_KEY_ID,
        sqlOpenHelper.C_name,
        sqlOpenHelper.C_grade};
private static final int[] to = new int[] {
        R.id.rId,
        R.id.rName,
        R.id.rGrade};

Registration register;
sqlOpenHelper oh;
SQLiteDatabase db;
Cursor cursor;
SimpleCursorAdapter cursorAdapter;
ListView list;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_database);
    list = (ListView) findViewById(R.id.listView);
    oh = new sqlOpenHelper(this, oh.DATABASE_NAME, null, oh.VERSION);
    db = oh.getReadableDatabase();
    register = new Registration(this);
    cursor = register.print();
    cursorAdapter = new SimpleCursorAdapter(this, R.layout.rows, cursor, from, to);
    list.setAdapter(cursorAdapter);
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_view_database, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="10dp"
    android:orientation="horizontal"
    android:id="@+id/name">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="Name"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/editName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="Name" />

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:orientation="horizontal"
    android:layout_below="@id/name">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="Grade"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/editGrade"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:ems="10"
        android:inputType="number"
        android:hint="Grade"/>
</LinearLayout>

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:text="Add"
    android:onClick="addButton"/>
</RelativeLayout>

enter image description here

rows.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

<TextView
    android:id="@+id/rId"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:textSize="30sp"/>

<TextView
    android:id="@+id/rName"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:textSize="30sp"/>

<TextView
    android:id="@+id/rGrade"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:textSize="30sp"/>

</LinearLayout>

adtivity_view_database.xml

   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.example.brothers.sql.ViewDatabase">

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/listView"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true" />

</RelativeLayout>

听说是logcat

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.brothers.sql/com.example.brothers.sql.ViewDatabase}: java.lang.IllegalArgumentException: column '_id' does not exist
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2343)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2395)
            at android.app.ActivityThread.access0(ActivityThread.java:162)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
            at android.os.Handler.dispatchMessage(Handler.java:107)
            at android.os.Looper.loop(Looper.java:194)
            at android.app.ActivityThread.main(ActivityThread.java:5371)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
            at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalArgumentException: column '_id' does not exist

看着你的logcat:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.brothers.sql/com.example.brothers.sql.ViewDatabase}: java.lang.IllegalArgumentException: column '_id' does not exist

看起来,您的数据库中没有名为 '_id' 的列,但是,您在代码中 using/calling 它。

问题已解决。我在 Content Provider 部分的 developer.android.com 中找到了答案:

Note: A provider isn't required to have a primary key, and it isn't required to use _ID as the column name of a primary key if one is present. However, if you want to bind data from a provider to a ListView, one of the column names has to be _ID. This requirement is explained in more detail in the section Displaying query results.

听说是原文link:

http://developer.android.com/guide/topics/providers/content-provider-basics.html