本文所有代码均存放于
https://github.com/MADMAX110/Starbuzz
之前了解了如何修改应用让它从SQLite数据库中提取数据,但是还没有用过更新过数据库数据。
这里要修改应用使用户能够记录哪些饮料是他们的最爱。为此要为DrinkActivity增加一个复选框;
如果选中这个复选框,就说明当前饮料是用户的一个最爱。
还要为TopLevelActivity增加一个新的列表视图,其中包含用户最喜欢的饮料。
一、更新DrinkActivity
在之前的数据库中已经为DRINK表增加了一个FAVORITE列,下面要让用这个列让用户指示某个饮料是否是他的一个最爱。我们会在一个新的复选框中显示这个值,用户单击这个复选框时要用这个新值更新FAVORITE列。
1、向DrinkActivity的布局增加一个复选框
先增加一个字符串资源
<string name="favorite">Favorite</string>
在activity_drink.xml中增加一个复选框
<CheckBox
android:id = "@+id/favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/favorite"
android:onClick="onFavoriteClicked"/>
要使返回的数据包含FAVORITE列,只需要把FAVORITE列增加到游标返回的列名数组。
Cursor cursor = db.query("DRINK",
new String[]{"NAME", "DESCRIPTION", "IMAGE_RESOURCE_ID", "FAVORITE"},
"_id = ?",
new String[] {Integer.toString(drinkId)},
null, null, null);
有了FAVORITE这个列的值后,就可以相应的更新favorite复选框。要得到这个值,首先导航到游标的第一个(也是唯一一个记录)。
cursor.moveToFirst()
然后得到当前饮料的FAVORITE列的值。FAVORITE列包含数值0和1。
1就选中复选框,0就不选中复选框:
boolean isFavorite = (cursor.getInt(3) == 1);
CheckBox favorite = (CheckBox) findViewById(R.id.favorite);
favorite.setChecked(isFavorite);
响应单击事件来更新数据库。
2、完整的DrinlkActivity代码
package com.hfad.starbuzz;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class DrinkActivity extends AppCompatActivity {
public static final String EXTRA_DRINKID = "drinkId";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink);
int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);
SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);
try {
SQLiteDatabase db = starbuzzDatabaseHelper.getReadableDatabase();
Cursor cursor = db.query("DRINK",
new String[]{"NAME", "DESCRIPTION", "IMAGE_RESOURCE_ID", "FAVORITE"},
"_id = ?",
new String[] {Integer.toString(drinkId)},
null, null, null);
if (cursor.moveToFirst()) {
String nameText = cursor.getString(0);
String descriptionText = cursor.getString(1);
int photoId = cursor.getInt(2);
boolean isFavorite = (cursor.getInt(3) == 1);
TextView name = (TextView) findViewById(R.id.name);
name.setText(nameText);
TextView description = (TextView) findViewById(R.id.description);
description.setText(descriptionText);
ImageView photo = (ImageView) findViewById(R.id.photo);
photo.setImageResource(photoId);
photo.setContentDescription(nameText);
CheckBox favorite = (CheckBox) findViewById(R.id.favorite);
favorite.setChecked(isFavorite);
}
cursor.close();
db.close();
}catch (SQLException e){
Toast toast = Toast.makeText(this,
"Database unavailable",
Toast.LENGTH_SHORT);
toast.show();
}
}
public void onFavoriteClicked(View view){
int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);
CheckBox favorite = (CheckBox) findViewById(R.id.favorite);
ContentValues drinkValues = new ContentValues();
drinkValues.put("FAVORITE", favorite.isChecked());
SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);
try{
SQLiteDatabase db = starbuzzDatabaseHelper.getWritableDatabase();
db.update("DRINK",
drinkValues,
"_id = ?",
new String[] {Integer.toString(drinkId)});
db.close();
}catch(SQLiteException e) {
Toast toast = Toast.makeText(this, "Database unavailable", Toast.LENGTH_SHORT);
toast.show();
}
}
}
二、在TopLevelActivity中显示用户的最爱
1、为TopLevelActivity的布局增加一个列表视图和一个文本视图
2、填充列表视图,并让它响应单击事件
3、选择一个新的最爱饮料时刷新列表视图数据
1、更新activity_top_level.xml
先增加字符串
<string name="favorites">Your favorite drinks:</string>
再在activity_top_level.xml中增加一个列表视图和文本视图
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/favorites" />
<ListView
android:id="@+id/list_favorites"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
2、更新TopLevelActivity
package com.hfad.starbuzz;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
public class TopLevelActivity extends AppCompatActivity {
private SQLiteDatabase db;
private Cursor favoritesCursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_top_level);
setupOptionsListView();
setupFavoritesListView();
}
private void setupOptionsListView() {
//创建监听器
AdapterView.OnItemClickListener itemClickListener =
new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Drink是列表视图中的第一项,所以位于位置0
if (position == 0) {
//这个意图来自TopLevelActivity,需要启动DrinkCategoryActivity
Intent intent = new Intent(TopLevelActivity.this, DrinkCategoryActivity.class);
startActivity(intent);
}
}
};
//为列表视图增加监听器
ListView listView = (ListView) findViewById(R.id.list_options);
listView.setOnItemClickListener(itemClickListener);
}
private void setupFavoritesListView() {
ListView listFavorites = (ListView) findViewById(R.id.list_favorites);
try{
SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);
db = starbuzzDatabaseHelper.getReadableDatabase();
favoritesCursor = db.query("DRINK",
new String[]{"_id", "NAME"},
"FAVORITE = 1",
null, null, null, null);
CursorAdapter favoriteAdapter = new SimpleCursorAdapter(TopLevelActivity.this,
android.R.layout.simple_list_item_1,
favoritesCursor,
new String[]{"NAME"},
new int[]{android.R.id.text1}, 0);
listFavorites.setAdapter(favoriteAdapter);
}catch (SQLiteException e){
Toast.makeText(this, "Database unavailable", Toast.LENGTH_SHORT).show();
}
listFavorites.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long id) {
Intent intent = new Intent(TopLevelActivity.this, DrinkActivity.class);
intent.putExtra(DrinkActivity.EXTRA_DRINKID, (int)id);
startActivity(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
favoritesCursor.close();
db.close();
}
}
3、游标不会自动刷新
如果用户导航到DrinkActivity来选择一个新的最爱饮料。这个新的最爱饮料不会自动显示在TopLevelActivity的list_favorites列表视图中。这是因为游标只在创建时获取数据。
需要使用changeCursor方法改变游标
向DrinkActivity中添加onRestart即可:
@Override
protected void onRestart() {
super.onRestart();
Cursor newCursor = db.query("DRINK",
new String[]{"_id", "NAME"},
"FAVORITE = 1",
null, null, null, null);
ListView listFavorites = (ListView) findViewById(R.id.list_favorites);
CursorAdapter adapter = (CursorAdapter) listFavorites.getAdapter();
adapter.changeCursor(newCursor);
favoritesCursor = newCursor;
}