我正在尝试使用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方法中获取光标后将它们解析为列表。
答案 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。