我试图创建一个基本的食物日志,人们可以在editTexts中输入食物名称和卡路里:
onClick方法应该接受他们的输入并添加到数据库,然后运行查询以检索食物列表并将其添加回布局,以及获得总卡路里。
在主要活动中:
// Add a food to the database
public void onClickAdd(View view) {
// Get the food stats from the layout
String foodName = txtFood.getText().toString();
String calString = txtCalories.getText().toString();
int calories = Integer.parseInt(calString);
Food food = new Food(foodName, calories);
// Add the new food (the name and the calories)
foodDBHandler.addProduct(food);
// Setting the new values in the textviews
printDatabase();
getTotalCalories();
}
public void printDatabase(){
String dbString = foodDBHandler.databaseToString();
txtFoodLog.setText(dbString);
txtFood.setText("");
}
//Get the total calories
public void getTotalCalories() {
int dbString = foodDBHandler.sumCalories();
txtTotalCals.setText("Total Cals: " + dbString);
txtCalories.setText("");
}
FoodDBHandler类运行printDatabase()和getTotalCalories()使用的查询:
// Gets a list of all the foods
public String databaseToString(){
String dbString = "";
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_FOOD + " WHERE 1";
//Cursor points to a location in your results
Cursor recordSet = db.rawQuery(query, null);
//Move to the first row in your results
recordSet.moveToFirst();
//Position after the last row means the end of the results
while (!recordSet.isAfterLast()) {
// null could happen if we used our empty constructor
if (recordSet.getString(recordSet.getColumnIndex("foodname")) != null) {
dbString += recordSet.getString(recordSet.getColumnIndex("foodname"));
dbString += "\n";
}
recordSet.moveToNext();
}
db.close();
return dbString;
}
public int sumCalories(){
/*
This method goes through the entire db, then checks if there are empty values in the food column
If the column is not null, then it takes the calorie value of the food and adds it on to the dbString value (which is an integer despite the name)
*/
int dbString = 0;
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_FOOD + " WHERE 1";
//Cursor points to a location in the results
Cursor recordSet = db.rawQuery(query, null);
//Move to the first row in your results
recordSet.moveToFirst();
//Position after the last row means the end of the results
while (!recordSet.isAfterLast()) {
// null could happen if we used our empty constructor
if (recordSet.getString(recordSet.getColumnIndex("foodname")) != null) {
dbString += recordSet.getInt(recordSet.getColumnIndex("calories"));
}
recordSet.moveToNext();
}
db.close();
return dbString;
}
问题是,当我点击onClickAdd按钮时,文本会从布局中消失,而不会从表中发回信息。
这是我更新内容或数据库本身的方式吗?
答案 0 :(得分:0)
我相信查询中存在一些问题
String query = "SELECT * FROM " + TABLE_FOOD + " WHERE 1";
理想情况下,您必须在查询中提供column_name
String query = "SELECT * FROM " + TABLE_FOOD + " WHERE QUANTITY = 1";
答案 1 :(得分:0)
由于您的问题的原因可能很多,这里有一个有效的应用程序示例。但是,它不使用看起来像TextView的东西来显示食物列表,而是使用ListView。
虽然不是一个具体的答案,但目的是提供一个可以突出问题并从而回答问题的工作实例。
public class MainActivity extends AppCompatActivity {
EditText txtFood, txtCalories;
Button mAddFood, mDeleteFood, mBack;
ListView mFoodListListView; //<<<< ListView rather than text with new lines
TextView txtTotalCals;
SimpleCursorAdapter mSCA; // <<<< Cursor Adapter for the ListView
Cursor mFoodListCursor; // <<<< Cursor to populate the ListView
FoodDBHandler fh; // <<<< DB Helper (CAN't BE INSTANIATED YET)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get Views form thier ID's
txtFood = (EditText) this.findViewById(R.id.et_food);
txtCalories = (EditText) this.findViewById(R.id.et_calories);
mAddFood = (Button) this.findViewById(R.id.btn_addfood);
mDeleteFood = (Button) this.findViewById(R.id.btn_dltfood);
mBack = (Button) this.findViewById(R.id.btn_back);
mFoodListListView = (ListView) this.findViewById(R.id.foodlist);
txtTotalCals = (TextView) this.findViewById(R.id.caloriecount);
// Instantiate the FoodHandler instance
fh = new FoodDBHandler(this);
// Load the Listview with data if any.
mFoodListCursor = fh.getAllFoods();
mSCA = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2,
mFoodListCursor,
new String[]{ FoodDBHandler.COL_FOOD_NAME, FoodDBHandler.COL_CALORIES},
new int[]{android.R.id.text1, android.R.id.text2},
0);
mFoodListListView.setAdapter(mSCA);
txtTotalCals.setText(fh.getTotalCalories());
//Set the Button click listeners
setAddFoodButtonListener();
setDeleteFoodButtonListener();
setBackButtonListener();
}
private void setBackButtonListener() {
mBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("BACKBUTTONCLICK","The back button was clicked.");
// finish(); commented out as this main activity
}
});
}
private void setAddFoodButtonListener() {
mAddFood.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (txtFood.length() < 1 || txtCalories.length() < 1) {
Toast.makeText(
getApplicationContext(),
"Unable to Add - Blank Value(s).",
Toast.LENGTH_LONG
).show();
return;
}
fh.addFood(
txtFood.getText().toString(),
Integer.valueOf(txtCalories.getText().toString()));
refreshListView();
}
});
}
private void setDeleteFoodButtonListener() {
mDeleteFood.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (txtFood.length() < 1 || txtCalories.length() < 1) {
Toast.makeText(
getApplicationContext(),
"Unable to Delete - Blank Value(s).",
Toast.LENGTH_LONG
).show();
return;
}
String foodname = txtFood.getText().toString();
long caloroies = Long.valueOf(txtCalories.getText().toString());
long id;
if ((id =fh.getIdFromNameAndCalories(foodname,caloroies)) > 0) {
if (fh.deleteFood(id)) {
Toast.makeText(
getApplicationContext(),
"Deleted.",
Toast.LENGTH_LONG
).show();
refreshListView();
} else {
Toast.makeText(
getApplicationContext(),
"Oooops not Deleted????",
Toast.LENGTH_LONG
).show();
}
} else {
Toast.makeText(
getApplicationContext(),
"Unable to Delete - Not Found.",
Toast.LENGTH_LONG
).show();
}
}
});
}
private void refreshListView() {
mFoodListCursor = fh.getAllFoods();
mSCA.swapCursor(mFoodListCursor);
txtTotalCals.setText(fh.getTotalCalories());
}
}
public class FoodDBHandler extends SQLiteOpenHelper {
public static final String DBNAME = "foods";
public static final int DBVERSION = 1;
public static final String TABLE_FOOD = "food";
public static final String COL_FOOD_ID = BaseColumns._ID;
public static final String COL_FOOD_NAME = "foodname";
public static final String COL_CALORIES = "calories";
Context mContext;
SQLiteDatabase mDB;
FoodDBHandler(Context context) {
super(context, DBNAME, null, DBVERSION);
mContext = context;
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crttblsql = "CREATE TABLE IF NOT EXISTS " +
TABLE_FOOD +
" (" +
COL_FOOD_ID + " INTEGER PRIMARY KEY, " +
COL_FOOD_NAME + " TEXT, " +
COL_CALORIES + " INTEGER " +
")";
db.execSQL(crttblsql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Gets a list of all the foods <<<< NO LONGER USED
public String databaseToString() {
String dbString = "";
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_FOOD + " WHERE 1";
//Cursor points to a location in your results
Cursor recordSet = db.rawQuery(query, null);
//Move to the first row in your results
recordSet.moveToFirst();
//Position after the last row means the end of the results
while (!recordSet.isAfterLast()) {
// null could happen if we used our empty constructor
if (recordSet.getString(recordSet.getColumnIndex("foodname")) != null) {
dbString += recordSet.getString(recordSet.getColumnIndex("foodname"));
dbString += "\n";
}
recordSet.moveToNext();
}
//NOTE! no cursor.close() SHOULD ALWAYS CLOSE A CURSOR WHEN DONE WITH IT
db.close();
return dbString;
}
// Example of how databaseToString could be written <<< NOT USED
public String altDatabaseToString() {
StringBuilder dbString = new StringBuilder();
Cursor recordset = mDB.query(TABLE_FOOD,null,null,null,null,null,null);
int columncount = recordset.getCount();
while (recordset.moveToNext()) {
dbString.append(recordset.getString(recordset.getColumnIndex(COL_FOOD_NAME)));
if (recordset.getPosition() < (columncount - 1)) {
dbString.append("\n");
}
}
recordset.close();
return dbString.toString();
}
// <<<< Equivalent to addProduct
public boolean addFood(String food, int calories) {
ContentValues cv = new ContentValues();
cv.put(COL_FOOD_NAME,food);
cv.put(COL_CALORIES,calories);
return mDB.insert(TABLE_FOOD,null,cv) > 0;
}
// <<<< deleteFood according to id column
public boolean deleteFood(long id) {
return mDB.delete(TABLE_FOOD,COL_FOOD_ID + "=?",new String[]{String.valueOf(id)}) > 0;
}
// <<<< get the id column according to name and calorie columns
// NOTE! will only allow return of id if there is no ambiguity
// i.e. name/calorie combination must be unique
public long getIdFromNameAndCalories(String foodname, long calroies) {
long rv = -1;
Cursor csr = mDB.query(TABLE_FOOD,
null,
COL_FOOD_NAME +
"=? AND "+
COL_CALORIES +
"=?",
new String[]{foodname,String.valueOf(calroies)},null,null,null);
// Ambiguous as extracted multiple rows i.e. which one to delete????
if (csr.getCount() > 1) {
return rv;
}
if (csr.moveToNext()) {
rv = csr.getLong(csr.getColumnIndex(COL_FOOD_ID));
}
csr.close();
return rv;
}
// <<<< Uses SQL features to get the sum of the calories
public String getTotalCalories() {
String rvcolumn = "caloriecount";
String rv = "0";
Cursor csr =mDB.query(TABLE_FOOD,
new String[]{"sum(" + COL_CALORIES +") AS " + rvcolumn},
null,null,
null,
null,
null
);
if (csr.moveToFirst()) {
rv = Integer.toString(csr.getInt(csr.getColumnIndex(rvcolumn)));
}
csr.close();
return rv;
}
// <<<< Simply get all rows from the database
public Cursor getAllFoods() {
return mDB.query(TABLE_FOOD,
null,
null,
null,
null,
null,
null
);
}
}
<?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"
tools:context="so.com.so48101940food.MainActivity">
<EditText
android:id="@+id/et_food"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="10"
android:hint="Your Food"
/>
<EditText
android:id="@+id/et_calories"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="10"
android:inputType="number"
android:hint="Calories"/>
<TextView
android:id="@+id/tv_record"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/foodlist"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50">
</ListView>
<TextView
android:id="@+id/caloriecount"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:orientation="horizontal"
android:id="@+id/buttons"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10">
<Button
android:layout_marginLeft="10dp"
android:id="@+id/btn_addfood"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Add"
/>
<Button
android:layout_marginRight="10dp"
android:id="@+id/btn_dltfood"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Delete"
/>
</LinearLayout>
<Button
android:id="@+id/btn_back"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>