我正在尝试使用Fragments学习一些Android开发,但遇到了问题。
我的应用程序需要多个表,因此我采用创建主数据库适配器的方法来创建所有表,并为每个表命令使用单独的适配器。
我遇到的问题是在recipe_Fragment中实例化recipe_Adapter以访问适配器中的命令。
有什么东西需要改变才能使Context Fragment友好吗?
我认为将所有适配器分开是最简洁的,对吧? 在一个大的主数据库适配器中为每个表包含所有命令会更好吗?
当我更改参数以适应片段时 - 按照Android Studio的指示 - 我在以下行中收到错误;错误表示找到了错误的第一个参数(即' context') 我已经尝试将其更改为Fragment但这给了我更多错误。
更新已解决!! 我将下面的片段类更改为工作版。我试图在片段创建之前访问数据库,所以我试图传递那些不存在的东西。新代码在try和catch语句中访问onActivityCreated()中的数据库。
主数据库适配器 包app.rory.pocket_chef.Adapters;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.sql.SQLException;
/**
* Created by Rory on 06/10/15.
*/
public class DBAdapter {
public static final String DATABASE_NAME = "pocket_chef";
public static final int DATABASE_VERSION = 1;
//creating each table
private static final String CREATE_TABLE_RECIPES = "create table if not exists recipes(" +
"_id INT PRIMARY KEY AUTOINCREMENT, " +
"name VARCHAR" +
"ingredents TEXT" +
"instructions TEXT" +
"description TEXT" +
"time TIME)";
private static final String CREATE_TABLE_SHOPPING_LIST = "create table if not exists shopping_list(" +
"_id INT PRIMARY KEY AUTOINCREMENT" +
"name TEXT" +
"quantity FLOAT)";
private static final String CREATE_TABLE_PUBLIC_DB = "create table if not exists public_db(" +
"_id INT PRIMARY KEY AUTOINCREMENT" +
"name TEXT" +
"number INT)";
private static final String CREATE_TABLE_CURRENT_CONTENTS = "create table if not exists current_contents(" +
"_id INT PRIMARY KEY AUTOINCREMENT" +
"name TEXT" +
"quantity FLOAT" +
"expiry DATE)";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
/**
* Constructor
* @param ctx
*/
public DBAdapter(Context ctx)
{
this.context = ctx;
this.DBHelper = new DatabaseHelper(this.context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_RECIPES);
db.execSQL(CREATE_TABLE_SHOPPING_LIST);
db.execSQL(CREATE_TABLE_PUBLIC_DB);
db.execSQL(CREATE_TABLE_CURRENT_CONTENTS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
// Adding any table mods to this guy here
}
}
/**
* open the db
* @return this
* @throws SQLException
* return type: DBAdapter
*/
public DBAdapter open() throws SQLException
{
this.db = this.DBHelper.getWritableDatabase();
return this;
}
/**
* close the db
* return type: void
*/
public void close()
{
this.DBHelper.close();
}
}
单表适配器
package app.rory.pocket_chef.Adapters;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.sql.SQLException;
import app.rory.pocket_chef.Fragments.recipes_Fragment;
/**
* Created by Rory on 06/10/15.
*/
public class Recipes_Adapter {
public static final String ROW_ID = "_id";
public static final String NAME = "name";
public static final String INGREDIENTS = "ingredients";
public static final String INSTRUCTIONS = "instructions";
public static final String DESCRIPTION = "description";
public static final String TIME = "time";
private static final String DATABASE_TABLE = "recipes";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DBAdapter.DATABASE_NAME, null, DBAdapter.DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
/**
* Constructor - takes the context to allow the database to be
* opened/created
*
* @param ctx
* the Context within which to work
*/
public Recipes_Adapter(Context ctx) {
this.mCtx = ctx;
}
/**
* Open the recipes database. If it cannot be opened, try to create a new
* instance of the database. If it cannot be created, throw an exception to
* signal the failure
*
* @return this (self reference, allowing this to be chained in an
* initialization call)
* @throws SQLException
* if the database could be neither opened or created
*/
public Recipes_Adapter open() throws SQLException {
this.mDbHelper = new DatabaseHelper(this.mCtx);
this.mDb = this.mDbHelper.getWritableDatabase();
return this;
}
/**
* close return type: void
*/
public void close() {
this.mDbHelper.close();
}
/**
* Create a new recipe. If the recipe is successfully created return the new
* rowId for that recipe, otherwise return a -1 to indicate failure.
*
* @param name
* @param ingredients
* @param instructions
* @param description
* @param time
*
*
* @return rowId or -1 if failed
*/
public long createRecipe(String name, String ingredients, String instructions, String description, String time){
ContentValues initialValues = new ContentValues();
initialValues.put(NAME, name);
initialValues.put(INGREDIENTS, ingredients);
initialValues.put(INSTRUCTIONS, instructions);
initialValues.put(DESCRIPTION, description);
initialValues.put(TIME, time);
return this.mDb.insert(DATABASE_TABLE, null, initialValues);
}
/**
* Delete the recipes with the given rowId
*
* @param rowId
* @return true if deleted, false otherwise
*/
public boolean deleteRecipe(long rowId) {
return this.mDb.delete(DATABASE_TABLE, ROW_ID + "=" + rowId, null) > 0; //$NON-NLS-1$
}
/**
* Return a Cursor over the list of all recipes in the database
*
* @return Cursor over all recipes
*/
public Cursor getAllRecipes() {
return this.mDb.query(DATABASE_TABLE, new String[] { ROW_ID,
NAME, INGREDIENTS, INSTRUCTIONS, DESCRIPTION, TIME }, null, null, null, null, null);
}
/**
* Return a Cursor positioned at the recipe that matches the given rowId
* @param rowId
* @return Cursor positioned to matching recipe, if found
* @throws SQLException if recipe could not be found/retrieved
*/
public Cursor getRecipe(long rowId) throws SQLException {
Cursor mCursor =
this.mDb.query(true, DATABASE_TABLE, new String[] { ROW_ID, NAME,
INGREDIENTS, INSTRUCTIONS, DESCRIPTION ,TIME}, ROW_ID + "=" + rowId, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Update the recipe.
*
* @param rowId
* @param name
* @param ingredients
* @param instructions
* @param description
* @param time
*
* @return true if the note was successfully updated, false otherwise
*/
public boolean updateRecipe(long rowId, String name, String ingredients, String instructions, String description, String time){
ContentValues args = new ContentValues();
args.put(NAME, name);
args.put(INGREDIENTS, ingredients);
args.put(INSTRUCTIONS, instructions);
args.put(DESCRIPTION, description);
args.put(TIME, time);
return this.mDb.update(DATABASE_TABLE, args, ROW_ID + "=" + rowId, null) >0;
}
}
食谱片段
package app.rory.pocket_chef.Fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.sql.SQLException;
import app.rory.pocket_chef.Adapters.DBAdapter;
import app.rory.pocket_chef.Adapters.Recipes_Adapter;
import app.rory.slidemenu.R;
/**
* Created by Z0NEN on 10/22/2014.
*/
public class recipes_Fragment extends Fragment {
private Recipes_Adapter recipes;
private DBAdapter db;
View rootview;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.recipes_layout, container, false);
return rootview;
}
public void onActivityCreated (Bundle savedInstanceState) {
db = new DBAdapter(getActivity());
recipes = new Recipes_Adapter(getActivity());
try {
db.open();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
我解决了这个问题,我试图在片段创建之前访问数据库。我在onCreate()之后将以下代码添加到fragment类中,现在它可以正常工作
public void onActivityCreated (Bundle savedInstanceState) {
db = new DBAdapter(getActivity());
recipes = new Recipes_Adapter(getActivity());
try {
db.open();
} catch (SQLException e) {
e.printStackTrace();
}
}
答案 1 :(得分:0)
查看以下代码:
构造函数db
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
构造数据库对象
rootview = inflater.inflate(R.layout.recipes_layout, container, false);
DatabaseHelper database = new DatabaseHelper(rootview.getContext());
return rootview;
我不建议在适配器中包装数据库,我建议将这些问题分开以减少代码纠缠。
答案 2 :(得分:0)
创建每个表格...您会错过逗号以分隔每个字段 这就是你想要的:
//creating each table
private static final String CREATE_TABLE_RECIPES = "create table if not exists recipes(" +
"_id INT PRIMARY KEY AUTOINCREMENT, " +
"name VARCHAR, " +
"ingredents TEXT, " +
"instructions TEXT, " +
"description TEXT, " +
"time TIME)";
private static final String CREATE_TABLE_SHOPPING_LIST = "create table if not exists shopping_list(" +
"_id INT PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"quantity FLOAT)";
private static final String CREATE_TABLE_PUBLIC_DB = "create table if not exists public_db(" +
"_id INT PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"number INT)";
private static final String CREATE_TABLE_CURRENT_CONTENTS = "create table if not exists current_contents(" +
"_id INT PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"quantity FLOAT, " +
"expiry DATE)";
卸载并重新安装应用程序以重新创建数据库。