我正在研究我的第一个Android应用程序并遇到一个问题我似乎无法找到解决方案。我正在尝试使用一系列列表视图设置我的UI,这些列表视图最后将连接到显示需要输入的编辑文本的页面。 IE类别 - >来源 - >标题 - >换句话说,编辑我们将首先显示一个类别列表(音乐,电影等)。然后用户点击让我们说音乐,然后它会列出我的数据库中的艺术家。然后点击艺术家,它将在我的数据库中显示他们的歌曲。我有设置atm它将显示我设置的游标,但是我在设置我的程序时遇到问题,看看用户点击了什么,并给出结果/显示光标,其中包含我想要显示的数据。
public class dbadapter extends SQLiteOpenHelper {
//The Android's default system path of your application database.
public static final String DB_PATH = "/data/data/wanted.pro.madlibs/databases/";
public static final String DB_NAME = "madlib";
public static final int DB_VERSION = 1;
private static final String TAG = "dbadapter";
//database variables
public static final String KEY_ID = "_id";
public static final String KEY_CATEGORYDESC = "categorydesc";
public static final String KEY_TITLE = "titlekey";
public static final String KEY_TITLEDESC = "titledesc";
public static final String KEY_TITLESTORY = "titlestory";
public static final String KEY_SOURCEDESC = "sourcedesc";
public static final String KEY_SOURCE = "sourcekey";
public static final String KEY_CATEGORY = "categorykey";
//table variables
public static final String CATEGORY_TABLE = "category";
public static final String SOURCE_TABLE = "source";
public static final String TITLE_TABLE = "title";
private dbadapter mydbhelper;
private static SQLiteDatabase myDataBase;
@Override
public void onOpen(SQLiteDatabase myDatabase)
{
super.onOpen(myDatabase);
if (!myDatabase.isReadOnly())
{
// Enable foreign key constraints
myDatabase.execSQL("PRAGMA foreign_keys=ON;");
}
}
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* @param context
*/
private final Context mCtx;
public dbadapter(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.mCtx = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transferring bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = mCtx.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS category");
onCreate(db);
}
public dbadapter open() throws SQLException {
mydbhelper = new dbadapter (mCtx);
myDataBase = mydbhelper.getWritableDatabase();
return this;
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
// retrieves all the categories
public static Cursor getAllCategories()
{
return myDataBase.query(CATEGORY_TABLE, new String[] {
KEY_ID, KEY_CATEGORY,
KEY_CATEGORYDESC,
},
null, null, null, null, KEY_CATEGORYDESC);
}
// retrieves all the titles
public Cursor getAllTitles()
{
return myDataBase.query(TITLE_TABLE, new String[] {
KEY_ID,
KEY_TITLE,
KEY_TITLEDESC,
KEY_TITLESTORY,
},
null, null, null, null, KEY_TITLEDESC);
}
// retrieves all the sources
public Cursor getAllSources()
{
return myDataBase.query(SOURCE_TABLE, new String[] {
KEY_ID,
KEY_SOURCE,
KEY_SOURCEDESC,
},
null, null, null, null, KEY_SOURCEDESC);
}
以下是我的适配器
的代码public class categories extends ListActivity {
/** Called when the activity is first created. */
private dbadapter mydbhelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_list);
mydbhelper = new dbadapter(this);
mydbhelper.open();
fillData();
}
private void fillData() {
Cursor c = mydbhelper.getAllCategories();
startManagingCursor(c);
// Create an array to specify the fields we want to display in the list (TITLE,DATE,NUMBER)
String[] from = new String[] {dbadapter.KEY_CATEGORYDESC};
// an array of the views that we want to bind those fields to (in this case text1,text2,text3)
int[] to = new int[] {R.id.text1};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter adapter =
new SimpleCursorAdapter(this, R.layout.cate_row, c, from, to);
setListAdapter(adapter);
}
@Override
protected void onListItemClick(ListView list, View v, int position, long id)
{
super.onListItemClick(list, v, position, id);
final Intent intent = new Intent(this, source.class);
startActivityForResult(intent, position);
}
}
这将是我创建数据库表的SQL日志
CREATE TABLE category(
_id INT,
categorykey INT,
categorydesc TEXT,
PRIMARY KEY(_id)
);
CREATE TABLE source(
_id INT,
sourcekey INT,
sourcedesc TEXT,
PRIMARY KEY(_id)
);
CREATE TABLE title(
_id INT,
titlekey INT,
titledesc TEXT,
titlestory TEXT,
PRIMARY KEY(_id)
);
CREATE TABLE userword(
_id INT,
titlekey INT,
userword TEXT,
PRIMARY KEY(_id), FOREIGN KEY(titlekey) REFERENCES title(titlekey)
);
CREATE TABLE category_title(
titlekey INT,
categorykey INT,
FOREIGN KEY(titlekey) REFERENCES title(titlekey), FOREIGN KEY (categorykey) REFERENCES category(categorykey)
);
CREATE TABLE source_title(
titlekey INT,
sourcekey INT,
FOREIGN KEY(titlekey) REFERENCES title(titlekey), FOREIGN KEY (sourcekey) REFERENCES source(sourcekey)
);
CREATE TABLE source_category(
sourcekey INT,
categorykey INT,
FOREIGN KEY(categorykey) REFERENCES category(categorykey), FOREIGN KEY (sourcekey) REFERENCES source(sourcekey)
);
我知道我唯一正确的游标是类别,因为它是数据库表中唯一不会被之前选择过滤的数据。
答案 0 :(得分:1)
我使用类似的东西,我使用单独的表来保存我的列表。我不会像你将要使用的那样预先填充。我有一个列表视图由一个表列表填充,当您单击列表中的项目时,它会弹出另一个列表视图,该列表视图由所选表格中的条目填充。那是你要找的那种东西吗?
修改
再看一遍,
CREATE TABLE category(
_id INT,
categorykey INT,
categorydesc TEXT,
PRIMARY KEY(_id)
);
CREATE TABLE source(
_id INT,
sourcekey INT,
sourcedesc TEXT,
PRIMARY KEY(_id)
);
etc为每个创建一个单独的表,因此您需要更改表以获取其他列表。 public static final String CATEGORY_TABLE = "category";
只查询表类别以查询表格来源public static final String CATEGORY_TABLE = "source";
我所做的是使用列表视图中设置的变量
String click = l.getItemAtPosition(position).toString();
table = click;
<{1>} onListItemClick()
table
为public static String table;
,然后为您的查询使用table
而不是
答案 1 :(得分:1)
如果我的方案正确,你想知道如何确定选择了哪个对象(特别是哪个条目)。这可以很直接地完成,比尔加里给出了一个暗示。有两种选择:
对于正确的查询,您应该使用SELECT ... WHERE语句,您可以使用query()方法轻松实现该语句。但是,当你使用这种方法我认为你知道如何做到这一点。