无法使用sqlite数据库中的数据填充列表视图

时间:2015-02-24 16:01:32

标签: java android xml sqlite listview

我正在尝试学习Android开发。作为一个学习项目,我正在制作一个“待办事项”。应用。

我正在尝试使用我的表中的数据填充列表,这是我到目前为止所拥有的:

ListCursorAdapter.java

    package com.ryansmurphy.listado;

import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by ryanmurphy on 24/02/15.
 */
public class ListCursorAdapter extends CursorAdapter {

    public ListCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor, 0);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.item_todo, parent, false);
    }

    public void bindView(View view, Context context, Cursor cursor) {
        // Find fields to populate in inflated template
        TextView todo = (TextView) view.findViewById(R.id.todoText);
        // Extract properties from cursor
        String todoTextDB = cursor.getString(cursor.getColumnIndexOrThrow("todo"));
        // Populate fields with extracted properties
        todo.setText(todoTextDB);
    }
}

我在这里收到两个错误:

  1. extends cursor。我收到错误Cannot resolve symbol
  2. super(context, cursor, 0);。我收到错误Object() in Object cannot be applied to
  3. DatabaseHelper.java

    package com.ryansmurphy.listado;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    /**
     * Created by ryanmurphy on 23/02/15.
     */
    public class DatabaseHelper extends SQLiteOpenHelper {
    
        // Database Version
        private static final int DATABASE_VERSION = 1;
    
        // Database Name
        private static final String DATABASE_NAME = "listado";
    
        // Table Name
        private static final String TABLE_TODO = "todos";
    
    
        // Column names
        private static final String KEY_ID = "id";
        private static final String KEY_TODO = "todo";
        private static final String KEY_STATUS = "status";
        private static final String KEY_CREATED_AT = "created_at";
    
    
        // Table Create Statements
        // Todo table create statement
        private static final String CREATE_TABLE_TODO = "CREATE TABLE "
                + TABLE_TODO + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_TODO
                + " TEXT," + KEY_STATUS + " INTEGER," + KEY_CREATED_AT
                + " DATETIME" + ")";
    
        public DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
    
            // creating required table
            db.execSQL(CREATE_TABLE_TODO);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // on upgrade drop older tables
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_TODO);
    
            // create new tables
            onCreate(db);
        }
    
        public void addRecord()
        {
            SQLiteDatabase database = getWritableDatabase();
            ContentValues values = new ContentValues();
            values.put("todo", "todo example");
            values.put("status", "not completed");
            database.insert("todos", null, values);
            database.close();
        }
    
        public Cursor getAll()
        {
            SQLiteDatabase database = getReadableDatabase();
            Cursor cursor = database.rawQuery("select * from todos",null);
            return cursor;
        }
    }
    

    现在我的listview个人行xml: list_item.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">
        <TextView
            android:id="@+id/todoText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="24dp"
            android:padding="6dp" />
    </LinearLayout>
    

    ActivityMain.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=".MainActivity">
        <TextView android:text="To Do List" android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/title" />
        <ListView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/listview"
            android:layout_below="@id/title"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginTop="42dp" />
    </RelativeLayout>
    

    MainActivity.Java

    package com.ryansmurphy.listado;
    
    import android.content.Intent;
    import android.database.Cursor;
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.ListView;
    
    
    public class MainActivity extends ActionBarActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ListView lvItems = (ListView) findViewById(R.id.listview);
            // Setup cursor adapter using cursor from last step
            DatabaseHelper db = new DatabaseHelper();
            Cursor allRows = db.getAll();
            ListCursorAdapter todoAdapter = new ListCursorAdapter(this, allRows);
            //Attach cursor adapter to the ListView
            lvItems.setAdapter(todoAdapter);
        }
    
        @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.addItem)
            {
                addItem();
            }
    
            return super.onOptionsItemSelected(item);
        }
    
        public void addItem()
        {
            Intent addItemIntent= new Intent(MainActivity.this, AddItem.class);
            startActivity(addItemIntent);
        }
    }
    

    我在这里遇到两个错误:

    1. DatabaseHelper db = new DatabaseHelper();。我收到错误DatabaseHelper(Context) in DatabaseHelper cannot be applied
    2. lvItems.setAdapter(todoAdapter);。我收到错误setAdapter(android.widget.ListAdapter) in ListView cannot be applied
    3. 以上我从谷歌搜索,尝试和尝试。我从来没有真正知道我从一开始就做了什么,但我慢慢地接受了这一点,我想知道你们是否可以帮我解决这个问题。感谢

1 个答案:

答案 0 :(得分:1)

我将您的代码复制到一个新项目并进行了一些更改以使其正常工作。我完全剥离了一些区域 - 例如getAll()方法,我将其替换为MainActivity中的查询。 Here是首次加载时应用程序的样子,here是点击“添加”几次后的样子。

对于它的价值,我认为有更简单的方法可以实现这一目标 - 例如,使用SimpleCursorAdapter,这将无需创建自己的自定义Adapter类,并通过MainActivity延长ListActivityListFragment。但是,我坚持使用你的方法。

除了删除getAll()方法之外,我对DatabaseHelper做了以下小改动:

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE todos (_id INTEGER PRIMARY KEY, todo TEXT, status INTEGER, created_at INTEGER);");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.e(getClass().getSimpleName(), "onUpgrade: this is  not required.");
}

我更改了冗长的连接String CEATE_TABLE_TODO因为我觉得它更容易阅读。我还更改了列,以便它们包含文本和数字的混合。我还更换了onUpgrade()方法以获取简单的错误消息,因为我们不应在测试期间使用onUpgrade(),因为只有在升级已经发布的应用时才需要它。

我对ListCursorAdapter进行了一些小的更改,以便信息显示有用的内容 - 在这种情况下,String位于cursor.getString(1)(第一列)。

public class ListCursorAdapter extends CursorAdapter {

LayoutInflater inflater;

public ListCursorAdapter(Context context, Cursor cursor) {
    super(context, cursor, 0);
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return inflater.inflate(R.layout.list_item, parent, false);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
    TextView todo = (TextView) view.findViewById(R.id.todoText);
    String todoTextDB = cursor.getString(1);
    todo.setText(todoTextDB);
}
}

MainActivity中,您的DatabaseHelper需要一个context参数,我使用this来实现该参数。 (如果你回顾DatabaseHelper中的构造函数,你可以看到这个:

public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

除此之外,我所做的唯一重大改变是将DatabaseHelper query移至MainActivity,我将其置于名为runCursor()的方法中,以便我们更新每次我们使用ListView添加新项目时都会addItem()

public class MainActivity extends ActionBarActivity {

DatabaseHelper db;
ListView lv;
ListCursorAdapter adapter;
Cursor allRows;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    db = new DatabaseHelper(this);

    lv = (ListView) findViewById(R.id.list);
    adapter = new ListCursorAdapter(this, runCursor());
    lv.setAdapter(adapter);
}

@Override
public void onDestroy(){
    if (allRows != null) {
        allRows.close();
    }
    adapter.getCursor().close();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }

    if(id == R.id.addItem)
    {
        addItem();
    }

    return super.onOptionsItemSelected(item);
}

public void addItem()
{
   db.addRecord();
    adapter.changeCursor(runCursor());
}

Cursor runCursor() {
    Cursor allRows = null;
    allRows = db.getReadableDatabase().query(DatabaseHelper.TABLE_TODO,
            new String[] {DatabaseHelper.KEY_ID, DatabaseHelper.KEY_TODO},
            null, null, null, null, null);
    return allRows;
    }
}

我还应该提一下,我通过覆盖onDestroy()显式关闭任何游标对象,因为它们容易发生内存泄漏。我还没有在这里做的最后一句话是,最好将任何游标query()移动到后台线程,如AsyncTask。有关Android Developer page Cursor的更多信息,我建议您这样做!希望这很有用!