- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我是 Android Studio 的新手,
我已经有包含 3 列(ID、标题、详细信息)的数据库文件
我想创建一个包含来自数据库的“标题”的 ListView,当我单击其中一个标题时,它将转到下一个 Activity 并显示我之前单击的标题的“详细信息”。
数据库文件位于 Assets 文件夹中。
我正在使用 Android Studio 最新版本,请帮助我 xml、java 和 list 代码。谢谢。
这是我的代码,我只成功地在 ListView 中显示“标题”列,我不知道如何做其余的事情。
public class MainActivity extends AppCompatActivity {
static final String DBNAME = "story.db";
static final String DBASSETPATH = "databases/" + DBNAME;
static final String DBTABLE = "table";
static final String DBTITLE = "title";
static final String IDCOLUMN = "_id";
ListView mTableList;
SQLiteDatabase mDB;
SimpleCursorAdapter mSCA;
Cursor mCsr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTableList = (ListView) this.findViewById(R.id.storylist);
mDB = openStoryDB();
if (mDB != null) {
mCsr = mDB.query(DBTABLE,
new String[]{IDCOLUMN + " AS _id",
DBTITLE
},
null,null,null,null,null);
mSCA = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1,mCsr,
new String[]{DBTITLE},
new int[]{android.R.id.text1},0);
mTableList.setAdapter(mSCA);
} else {
Toast.makeText(this,"Unable to open Database.",Toast.LENGTH_LONG);
}
}
private SQLiteDatabase openStoryDB() {
String dbpath = this.getDatabasePath(DBNAME).getPath();
if (this.getDatabasePath(DBNAME).exists()) {
Log.d("OPENSTORYDB","Opening already existing Database");
return SQLiteDatabase.openDatabase(dbpath,null,SQLiteDatabase.OPEN_READWRITE);
}
InputStream is;
byte[] buffer;
FileOutputStream db;
try {
is = this.getAssets().open(DBASSETPATH);
buffer = new byte[is.available()];
is.read(buffer);
is.close();
} catch (Exception e) {
e.printStackTrace();
Log.d("OPENSTORYDB","Unable to locate or buffer input from assets " + DBASSETPATH);
return null;
}
// Just in case the databases directory doesn't exist create it.
File dbmkdir = (this.getDatabasePath(DBNAME)).getParentFile();
dbmkdir.mkdirs();
try {
db = new FileOutputStream(this.getDatabasePath(DBNAME).getPath());
} catch (Exception e) {
e.printStackTrace();
Log.d("OPENSTORYDB","Unable to create outputstream for DB at path " + dbpath);
try {
is.close();
} catch (Exception e2) {
}
return null;
}
try {
db.write(buffer);
db.flush();
db.close();
is.close();
} catch (Exception e) {
Log.d("OPENSTORYDB","Failed to copy asset to DB");
e.printStackTrace();
return null;
}
return SQLiteDatabase.openDatabase(dbpath,null,SQLiteDatabase.OPEN_READWRITE);
}
}
<?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="match_parent"
tools:context="com.book.story.MainActivity">
<ListView
android:id="@+id/storylist"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
最佳答案
你需要
以下是根据您的问题举例。
名为 mydb 的数据库,因此在 Assets 文件夹中有一个名为 mydb 的文件,包含表 mytable,其中包含:-
一个简单的布局,包括一个 Listview,该 id 已用于名为 MainActivity 的 Activity ,ListView 的代码是:-
<ListView
android:id="@+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
数据库助手已创建为 DBHelper.java。实例化时,它会检查数据库是否作为文件存在,如果不存在,则它会尝试从 Assets 文件夹中复制数据库(如果失败,则会抛出运行时异常,例如,如果 Assets 不存在)。然后打开数据库。有一种公共(public)方法 getAllFromMytable 返回一个 Cursor,其中包含 mytable 表中的所有行:-
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb"; //<<<<<<<<<< Database file name including extension
public static final int DBVERSION = 101;
public static final String TBL_MYTABLE = "mytable"; //<<<<<<<<<< The table name
public static final String COL_MYTABLE_ID = "id"; //<<<<<<<<<< The id column name
public static final String COl_MYTABLE_TITLE = "title"; //<<<<<<<<<< The title column name
public static final String COL_MYTABLE_DETAILS = "details"; //<<<<<<<<<< The details column name
Context mContext;
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mContext = context;
if(!ifDBExists()) {
copyDatabaseFromAssetsFolder();
}
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onDowngrade(db, oldVersion, newVersion);
}
public Cursor getAllFromMytable() {
String[] columns = new String[]{"*, id AS " + BaseColumns._ID}; //<<<<<<<<<< need column named _id so generate it
return mDB.query(TBL_MYTABLE,columns,null,null,null,null,null);
}
private void copyDatabaseFromAssetsFolder() {
int stage = 0, buffer_size = 4096, blocks_copied = 0, bytes_copied = 0;
try {
InputStream is = mContext.getAssets().open(DBNAME);
stage++;
OutputStream os = new FileOutputStream(mContext.getDatabasePath(DBNAME));
stage++;
byte[] buffer = new byte[buffer_size];
int length;
while ((length = is.read(buffer))>0) {
blocks_copied++;
os.write(buffer, 0, length);
bytes_copied += length;
}
os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
String exception = "";
switch (stage) {
case 0:
exception = "Unable to open asset file " + DBNAME;
break;
case 1:
exception = "Unable to open the Database file " + DBNAME + " for output.";
break;
case 2:
exception = "Error whilst copying " + DBNAME +
" from the assets folder to " + mContext.getDatabasePath(DBNAME).toString() +
" - successfully copied " + String.valueOf(blocks_copied) + " blocks."
;
}
throw new RuntimeException(exception + " (see stack-trace above)");
}
}
// Check if the Database exists
private boolean ifDBExists() {
File db = mContext.getDatabasePath(DBNAME);
if (db.exists()) return true;
if (!db.getParentFile().exists()) {
db.getParentFile().mkdirs();
}
return false;
}
}
这进行了 4-7,除了通过 Toast 显示 ListView 中被点击项目的详细信息而不是开始另一个 Activity :-
public class MainActivity extends AppCompatActivity {
ListView mMyListView;
DBHelper mDBHlpr;
Cursor mCsr;
SimpleCursorAdapter mSCA;
Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
mDBHlpr = new DBHelper(this); //<<<<<<<<<< Instantiate the DBHelper
mMyListView = this.findViewById(R.id.myListView);
}
private void manageListView() {
mCsr = mDBHlpr.getAllFromMytable(); //<<<<<<<<<< get the latest data from the database
if (mSCA == null) {
mSCA = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,mCsr,
new String[]{DBHelper.COl_MYTABLE_TITLE},
new int[]{android.R.id.text1},
0
);
mMyListView.setAdapter(mSCA);
mMyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Start the other activity here passing the id (sufficient to find the specififc row)via an intent extra
// Toast used as an example of extracting the respective data from the cursor
Toast.makeText(
mContext,
"You clicked on the row with an id of " + String.valueOf(id) +
" the Title is " + mCsr.getString(mCsr.getColumnIndex(DBHelper.COl_MYTABLE_TITLE)) +
" the Details are " + mCsr.getString(mCsr.getColumnIndex(DBHelper.COL_MYTABLE_DETAILS)) +
" the id column is " + String.valueOf(mCsr.getLong(mCsr.getColumnIndex(DBHelper.COL_MYTABLE_ID))),
Toast.LENGTH_SHORT
).show();
}
});
} else {
mSCA.swapCursor(mCsr);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mCsr.close(); //<<<<<<<<<< ensure that the cursor is closed when done with
}
@Override
protected void onResume() {
super.onResume();
manageListView(); //<<<<<<<<<< refresh the listview
}
}
Toast 的屏幕截图:-
将 id 传递给另一个 Activity ,然后提取该 Activity 中的详细信息列。
首先,在数据库助手类中添加一个新的方法,让details列以字符串的形式返回,并根据id
获取例如上面的 DBHelper.java 将添加以下内容:-
public String getDetailsFromId(long id) {
String rv = "";
String whereclause = COL_MYTABLE_ID + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
Cursor csr = mDB.query(TBL_MYTABLE,null,whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
rv = csr.getString(csr.getColumnIndex(COL_MYTABLE_DETAILS));
}
csr.close();
return rv;
}
创建其他 Activity 确保它在 list 中定义(使用 File/New/Activity 相应地修改 list )。
此 Activity 可能类似于(这将根据用于启动 Activity 的 intent extra 传递的 id 显示详细信息):-
public class OtherActivity extends AppCompatActivity {
public static final String INTENTKEY_MYTABLEIDCOLUMNS = "ikey_mytableidcolumn";
TextView mDetails;
DBHelper mDBHlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
mDetails = this.findViewById(R.id.mydetails);
mDBHlpr = new DBHelper(this);
long id = this.getIntent().getLongExtra(INTENTKEY_MYTABLEIDCOLUMNS,-1);
mDetails.setText(mDBHlpr.getDetailsFromId(id));
}
}
最后修改初始 Activity 以实例化可用于启动其他 Activity 的 Intent,然后将 id 作为额外的并最终启动其他 Activity ,例如在上述 Activity 中可以使用以下内容代替(如果您愿意的话)Toast:-
mMyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Start the other activity here passing the id (sufficient to find the specififc row)via an intent extra
// Toast used as an example of extracting the respective data from the cursor
/*
Toast.makeText(
mContext,
"You clicked on the row with an id of " + String.valueOf(id) +
" the Title is " + mCsr.getString(mCsr.getColumnIndex(DBHelper.COl_MYTABLE_TITLE)) +
" the Details are " + mCsr.getString(mCsr.getColumnIndex(DBHelper.COL_MYTABLE_DETAILS)) +
" the id column is " + String.valueOf(mCsr.getLong(mCsr.getColumnIndex(DBHelper.COL_MYTABLE_ID))),
Toast.LENGTH_SHORT
).show();
*/
Intent i = new Intent(mContext,OtherActivity.class);
i.putExtra(OtherActivity.INTENTKEY_MYTABLEIDCOLUMNS,id);
startActivity(i);
}
});
结果(根据单击项目时的其他 Activity (在本例中为第一个)):-
关于android - 使用 ListView 在下一个 Activity 中显示数据库详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54891896/
我的问题是如何在 python 中创建一个简单的数据库。我的例子是: User = { 'Name' : {'Firstname', 'Lastname'}, 'Address' : {'Street
我需要创建一个与远程数据库链接的应用程序! mysql 是最好的解决方案吗? Sqlite 是唯一的本地解决方案吗? 我使用下面的方法,我想知道它是否是最好的方法! NSString *evento
给定两台 MySQL 服务器,一台本地,一台远程。两者都有一个包含表 bohica 的数据库 foobar。本地服务器定义了用户 'myadmin'@'%' 和 'myadmin'@'localhos
我有以下灵活的搜索查询 Select {vt:code},{vt:productcode},{vw:code},{vw:productcode} from {abcd AS vt JOIN wxyz
好吧,我的电脑开始运行有点缓慢,所以我重置了 Windows,保留了我的文件。因为我的大脑还没有打开,所以我忘记事先备份我的 MySQL 数据库。我仍然拥有所有原始文件,因此我实际上仍然拥有数据库,但
如何将我的 Access 数据库 (.accdb) 转换为 SQLite 数据库 (.sqlite)? 请,任何帮助将不胜感激。 最佳答案 1)如果要转换 db 的结构,则应使用任何 DB 建模工具:
系统检查发现了一些问题: 警告:?:(mysql.W002)未为数据库连接“默认”设置 MySQL 严格模式 提示:MySQL 的严格模式通过将警告升级为错误来修复 MySQL 中的许多数据完整性问题
系统检查发现了一些问题: 警告:?:(mysql.W002)未为数据库连接“默认”设置 MySQL 严格模式 提示:MySQL 的严格模式通过将警告升级为错误来修复 MySQL 中的许多数据完整性问题
我想在相同的 phonegap 应用程序中使用 android 数据库。 更多说明: 我创建了 phonegap 应用程序,但 phonegap 应用程序不支持服务,所以我们已经在 java 中为 a
Time Tracker function clock() { var mytime = new Date(); var seconds
我需要在现有项目上实现一些事件的显示。我无法更改数据库结构。 在我的 Controller 中,我(从 ajax 请求)传递了一个时间戳,并且我需要显示之前的 8 个事件。因此,如果时间戳是(转换后)
我有一个可以收集和显示各种测量值的产品(不会详细介绍)。正如人们所期望的那样,显示部分是一个数据库+建立在其之上的网站(使用 Symfony)。 但是,我们可能还会创建一个 API 来向第三方公开数据
我们将 SQL Server 从 Azure VM 迁移到 Azure SQL 数据库。 Azure VM 为 DS2_V2、2 核、7GB RAM、最大 6400 IOPS Azure SQL 数据
我正在开发一个使用 MongoDB 数据库的程序,但我想问在通过 Java 执行 SQL 时是否可以使用内部数据库进行测试,例如 H2? 最佳答案 你可以尝试使用Testcontainers Test
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 已关闭 9 年前。 此问题似乎与 a specific programming problem, a sof
我正在尝试使用 MSI 身份验证(无需用户名和密码)从 Azure 机器学习服务连接 Azure SQL 数据库。 我正在尝试在 Azure 机器学习服务上建立机器学习模型,目的是我需要数据,这就是我
我在我的 MySQL 数据库中使用这个查询来查找 my_column 不为空的所有行: SELECT * FROM my_table WHERE my_column != ""; 不幸的是,许多行在
我有那个基地:http://sqlfiddle.com/#!2/e5a24/2这是 WordPress 默认模式的简写。我已经删除了该示例不需要的字段。 如您所见,我的结果是“类别 1”的两倍。我喜欢
我有一张这样的 table : mysql> select * from users; +--------+----------+------------+-----------+ | userid
我有表: CREATE TABLE IF NOT EXISTS `category` ( `id` int(11) NOT NULL, `name` varchar(255) NOT NULL
我是一名优秀的程序员,十分优秀!