gpt4 book ai didi

android - 使用 ListView 在下一个 Activity 中显示数据库详细信息

转载 作者:搜寻专家 更新时间:2023-10-30 22:24:44 26 4
gpt4 key购买 nike

我是 Android Studio 的新手,

我已经有包含 3 列(ID、标题、详细信息)的数据库文件

我想创建一个包含来自数据库的“标题”的 ListView,当我单击其中一个标题时,它将转到下一个 Activity 并显示我之前单击的标题的“详细信息”。

数据库文件位于 Assets 文件夹中。

我正在使用 Android Studio 最新版本,请帮助我 xml、java 和 list 代码。谢谢。

这是我的代码,我只成功地在 ListView 中显示“标题”列,我不知道如何做其余的事情。

主 Activity .java

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);
}
}

主 Activity .xml

<?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>

最佳答案

你需要

  1. 将 ListView 添加到初始 Activity 的适当布局。
  2. 创建一个数据库助手类,它将:
    1. 检查数据库是否已经存在
    2. 如果数据库不存在,则从 Assets 文件夹中复制数据库
    3. 根据需要提供访问数据的方法(在填充 Listview 的情况下,需要一个方法来检索要列出的数据)
  3. 在初始 Activity 中获取数据库助手类的实例
  4. 通过它的 id 获取 ListView。
  5. 为 ListView 实例化一个合适的适配器。
  6. 设置 ListView 使用适配器
  7. 将 onItemClick 监听器添加到 ListView,它将从所选项目中提取足够的详细信息(id),使用详细信息设置 Intent extra(s),然后启动其他 Activity (然后可以从 Intent 中提取详细信息) .

例子

以下是根据您的问题举例。

数据库

名为 mydb 的数据库,因此在 Assets 文件夹中有一个名为 mydb 的文件,包含表 mytable,其中包含:-

enter image description here

布局

一个简单的布局,包括一个 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;
}
}

主要 Activity

这进行了 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
}
}

注意事项

  • 请引用可以通过搜索轻松获得的评论和/或适当的文档
  • ManageListView 不会直接调用,因为 onResume 方法会在 Activity 启动时运行。

结果

Toast 的屏幕截图:-

enter image description here

附加

将 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 (在本例中为第一个)):-

enter image description here

关于android - 使用 ListView 在下一个 Activity 中显示数据库详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54891896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com