如何在Android中使用SQLite获取和写入数据

时间:2016-04-18 20:08:18

标签: android sqlite listview

我正在尝试使用SQLite来获取和设置列表视图的数据。我的列表必须包含初始数据,用户必须能够编辑它。

我创建了一个Item类

public final class Items implements BaseColumns {
public static final String TABLE_NAME = "items";

public static final String COLUMN_NAME_TYPE= "itemType";
public static final String COLUMN_NAME_NAME = "itemName";
public static final String COLUMN_NAME_CALORIE = "calorie";


private long id = -1;
private String name;
private String type;
private int calorie;

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public Items(String type,String name, int score) {
    this.name = name;
    this.type=type;
    this.calorie = calorie;

}
public String getName() {
    return name;
}

public int getCalorie() {
    return calorie;
}

public void setName(String name) {
    this.name = name;
}

public void setId(long id) {
    this.id = id;
}

public void setCalorie(int calorie) {
    this.calorie = calorie;
}


public long getId() {
    return id;
}


public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("Item [id=");
    builder.append(id);
    builder.append(", name=");
    builder.append(name);
    builder.append(", calorie=");
    builder.append(calorie);
    builder.append("]");
    return builder.toString();
}

}

然后我创建了一个DB helper类,它包含了我需要的所有方法。 (请注意,它是一个混乱的类。虽然我正在努力获取数据库的数据,但我改变了很多东西。)

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String DB_NAME = "items.db";
    private static final int DB_VERSION = 1;


    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);

    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + Items.TABLE_NAME + " ("
                + Items._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + Items.COLUMN_NAME_TYPE + " TEXT,"
                + Items.COLUMN_NAME_NAME + " TEXT,"
                + Items.COLUMN_NAME_CALORIE + " INTEGER" + ");");

    }

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

    public void createItem(Items item) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        values.put(Items.COLUMN_NAME_NAME, item.getName());
        values.put(Items.COLUMN_NAME_TYPE, item.getName());
        values.put(Items.COLUMN_NAME_CALORIE, item.getCalorie());


        item.setId(db.insert(Items.TABLE_NAME, null, values));
        db.close();
    }


    public Cursor getItemsTypeOf(String type){
        SQLiteDatabase db = this.getWritableDatabase();
        String[] tableColumn=new String[]{Items.COLUMN_NAME_TYPE,  Items.COLUMN_NAME_NAME, Items.COLUMN_NAME_CALORIE};
        String whereClause= Items.COLUMN_NAME_TYPE+"="+type;

     //           +" FROM "+Items.TABLE_NAME
       //         +"WHERE "+Items.COLUMN_NAME_TYPE+"="+type;
        Cursor cur=db.query(Items.TABLE_NAME,tableColumn,whereClause,null,null,null,null);

        return cur;

    }
    public Cursor fetchAllItems() {
        SQLiteDatabase db = this.getReadableDatabase();

       Cursor cur=  db.query(Items.TABLE_NAME, new String[]{
                        Items.COLUMN_NAME_TYPE, Items.COLUMN_NAME_NAME, Items.COLUMN_NAME_CALORIE,
                }, null, null, null, null,
                Items.COLUMN_NAME_CALORIE + " DESC");
        db.close();
        return cur;

    }
    public Items getItem(long id){

       SQLiteDatabase db = this.getReadableDatabase();


        Cursor cursor =
                db.query(Items.TABLE_NAME, 
                        null, 
                        Items._ID+ "=?", 
                        new String[] { String.valueOf(id) }, 
                        null, 
                        null, 
                        null);


        if(cursor!=null&&cursor.moveToFirst()) {
          Items item = new Items(cursor.getString(1), cursor.getString(2),
                    cursor.getInt(3));
            item.setId(cursor.getLong(0));

            cursor.close();


            db.close();;
            return item;
        }
       cursor.close();


        db.close();;
        return null;
    }

}

因此,我的应用程序将在mainActivity中具有类别,而每个类别将解析匹配的数据并显示其列表。

这是MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DatabaseHelper dbHelper = new DatabaseHelper(this);
        dbHelper.createItem( new Items("Breakfast","egg",23));



    }
    public void onBreakfastSelected(View view) {
        startActivity(new Intent(this, ListActivity.class));
    }

}

以及显示类别项目的其他列表类。

     public class ListActivity extends Activity implements  AdapterView.OnItemClickListener {


    ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);

        ListView list = (ListView) findViewById(R.id.listView);
        list.setOnItemClickListener(this);
        DatabaseHelper dbHelper = new DatabaseHelper(this);
        dbHelper.createItem(new Items("a", "a", 12));

        Items item=dbHelper.getItem(-1);
        //System.out.print();
        adapter.add(item.getName());
        list.setAdapter(adapter);

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    }
}

我无法获取插入的任何数据。当我尝试使用getItem方法时,它给了我错误。此外,我不知道如何将光标分隔成不同的数据,以便在我在getItemsTypeOf方法中获取光标后将它们解析为列表。

1 个答案:

答案 0 :(得分:0)

你基本上需要5个组件。

显示/使用包含ListView的布局的活动。 您有 ListActivity

包含ListView的布局。 您有 activity_list (我假设您引用它)。

从数据库获取数据的方法。 您有 fetchAllItems()。 请注意,除非您想引入复杂性,否则必须有一个名为_id的列。虽然您已定义列,但 fetchAllItems 不会输出此列。您可以将其更改为使用*(所有列)而不是命名列,或将 _ID 包含为命名列。

ListView的每个行/条目/项的布局。 你似乎没有这个。这是一个非常简单的布局。

最后,您需要一个合适的适配器。游标适配器适用于Cursor。有一个简单的光标适配器。但是,我从未使用过。我一直使用自定义光标适配器非常容易。 你似乎没有这样的适配器。

我会在适当的时候添加一些例子。

示例1 - 包含ListView的布局(我已经离开了一个按钮的小轿车): -

<?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:id="@+id/aslbc_layout"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/standard_dummy_size"
    android:layout_marginTop="@dimen/activity_vertical_margin"
    android:layout_marginBottom="@dimen/activity_vertical_margin"
    android:layout_marginLeft="@dimen/activity_horizontal_margin"
    android:layout_marginRight="@dimen/activity_horizontal_margin"
    android:descendantFocusability="beforeDescendants"
    tools:context="mjt.shopper.ShopListByCursorActivity">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="@dimen/standard_button_height"
        android:layout_margin="@dimen/standard_dummy_size">
        <Button
            android:id="@+id/aslbcbtn01"
            android:layout_width="@dimen/standard_button_width"
            android:layout_height="@dimen/standard_button_height"
            android:text="@string/standarddonebutton"
            android:textColor="@color/colorNormalButtonText"
            android:textStyle="bold"
            android:backgroundTint="@color/colorNormalButton"
            android:onClick="aslbcDone">
        </Button>
        <Button
            android:id="@+id/aslbcbtn02"
            android:layout_width="@dimen/standard_button_width"
            android:layout_height="@dimen/standard_button_height"
            android:text="@string/standardaddbuttontext"
            android:textStyle="bold"
            android:textColor="@color/colorNormalButtonText"
            android:backgroundTint="@color/colorNormalButton"
            android:onClick="aslbcAddShop">
        </Button>
    </LinearLayout>

    <ListView
        android:id="@+id/aslbclv01"
        android:layout_width="match_parent"
        android:layout_height="@dimen/standard_listview_height"
        android:longClickable="true">
    </ListView>
</LinearLayout>

示例2 - 每个项目(条目或行)的布局 (请注意,我已将Visibility设置为字段。这是因为这仍在进行中并且它正在进行中如果我需要,我可以轻松打开它们。: -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="@dimen/standard_listview_row_height"
    android:padding="0dp"
    android:background="@color/colorlistviewroweven"
    tools:context=".ShopListEntryActivity">
    <TextView
        android:id="@+id/shop_id_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:layout_weight="0"
        android:singleLine="true"
        android:textSize="@dimen/standard_listview_text_size"
        android:textStyle="italic"
        android:visibility="gone"/>
    <TextView
        android:id="@+id/shop_name_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:layout_weight="0.3"
        android:singleLine="true"
        android:textSize="@dimen/standard_listview_text_size"
        android:textStyle="bold" />
    <TextView
        android:id="@+id/shop_order_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:textSize="@dimen/standard_listview_text_size"
        android:visibility="gone"/>
    <TextView
        android:id="@+id/shop_city_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:layout_weight="0.3"
        android:singleLine="true"
        android:textSize="@dimen/standard_listview_text_size"/>
    <TextView
        android:id="@+id/shop_street_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:layout_weight="0.4"
        android:singleLine="true"
        android:textSize="@dimen/standard_listview_text_size"/>
    <TextView
        android:id="@+id/shop_state_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:textSize="@dimen/standard_listview_text_size"
        android:visibility="gone"/>
    <TextView
        android:id="@+id/shop_phone_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:textSize="@dimen/standard_listview_text_size"
        android:visibility="gone"/>
    <TextView
        android:id="@+id/shop_notes_entry"
        android:layout_width="@dimen/standard_dummy_size"
        android:layout_height="match_parent"
        android:textSize="@dimen/standard_listview_text_size"
        android:visibility="gone"/>
</LinearLayout>

示例3 - 自定义光标适配器 (注意getView不是必需的,但保留,因为您可能会发现代码很有用 - 它会替换行颜色) 请注意,newView包含(膨胀)列表项目布局

class ShopsCursorAdapter extends CursorAdapter {
    public ShopsCursorAdapter(Context context, Cursor cursor, int flags) {
        super(context, cursor, 0);
    }

    @Override
    public View getView(int position, View convertview, ViewGroup parent) {
        View view = super.getView(position, convertview, parent);
        Context context = view.getContext();
        if (position % 2 == 0) {
            view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewroweven));
        } else {
            view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewrowodd));
        }
        return view;
    }
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.activity_shop_list_entry, parent, false);
    }
    @Override
    public void bindView(View view,Context context, Cursor cursor) {
        TextView textviewShopid = (TextView) view.findViewById(R.id.shop_id_entry);
        TextView textViewShopName = (TextView) view.findViewById(R.id.shop_name_entry);
        //TextView textViewShopOrder = (TextView) view.findViewById(R.id.shop_order_entry);
        TextView textViewShopStreet = (TextView) view.findViewById(R.id.shop_street_entry);
        TextView textViewShopCity = (TextView) view.findViewById(R.id.shop_city_entry);
        //TextView textViewShopState = (TextView) view.findViewById(R.id.shop_state_entry);
        //TextView textViewShopPhone = (TextView) view.findViewById(R.id.shop_phone_entry);
        //TextView textViewShopNotes = (TextView) view.findViewById(R.id.shop_notes_entry);

        textviewShopid.setText(cursor.getString(ShopperDBHelper.SHOPS_COLUMNN_ID_INDEX));
        textViewShopName.setText(cursor.getString(ShopperDBHelper.SHOPS_COLUMN_NAME_INDEX));
        //textViewShopOrder.setText(cursor.getString(ShopperDBHelper.SHOPS_COLUMN_ORDER_INDEX));
        textViewShopStreet.setText(cursor.getString(ShopperDBHelper.SHOPS_COLUMN_STREET_INDEX));
        textViewShopCity.setText(cursor.getString(ShopperDBHelper.SHOPS_COLUMN_CITY_INDEX));
        //textViewShopState.setText(cursor.getString(ShopperDBHelper.SHOPS_COLUMN_STATE_INDEX));
        //textViewShopPhone.setText(cursor.getString(ShopperDBHelper.SHOPS_COULMN_PHONE_INDEX));
        //textViewShopNotes.setText(cursor.getString(ShopperDBHelper.SHOPS_COULMN_NOTES_INDEX));
    }
}

示例4 - 使用ListView的Activity的onCreate部分: -

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shop_list_by_cursor);

        shoplistcursor = shopperdb.getShopsAsCursor();
        final ListView listview = (ListView) findViewById(R.id.aslbclv01);
        final ShopsCursorAdapter adapter = new ShopsCursorAdapter(this,shoplistcursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        listview.setAdapter(adapter);

注意 shoplistcursor 在类中定义(增加范围): -

public Cursor shoplistcursor;

shoplistcursor = shopperdb.getShopsAsCursor();在您的案例中将与mycursor = DatabaseHelper.fetchAllItems();一致。

以下是 getShopsAsCursor : -

    public Cursor getShopsAsCursor() {
        SQLiteDatabase db = this.getReadableDatabase();
        String sqlstr = "SELECT * FROM " + SHOPS_TABLE_NAME +
                " ORDER BY " + SHOPS_COLUMN_NAME + ", " + SHOPS_COLUMN_CITY + ";";
        return db.rawQuery(sqlstr,null);
    }

在适配器中,(例3), SHOPS_COLUMN _ ???? _ INDEX 等于相应光标列的偏移量,例如: _id 是表格中的第一列,它的偏移量为 0 ,因此 SHOPS_COLUMN_ID_INDEX 等于0. name < / strong>是表格中的列,因此 SHOPS_COLUMN_NAME_INDEX 等同于 1

这是第1阶段,它不允许你编辑或添加。我建议先让清单工作。但是,你可能已经注意到在例如1的布局中有两个按钮,一个是Done按钮,就像后面一样(即代码只是 finish())。第二个是Add按钮,允许通过使用TextEdits开始另一个活动来添加新条目,以便输入新数据。

至于编辑;在现有数据中,代码(未在示例4中示出)包括onItemCLicked侦听器和代码,然后允许编辑行数据(这实际上使用相同的活动和相应调整的布局)。它还包括一个可以删除所选行的onItemLongClick。

我准备好后可以修改这个问题。只需评论您准备好在评论中包含@MikeT。