从 Android 应用打印日记条目
Posted
技术标签:
【中文标题】从 Android 应用打印日记条目【英文标题】:Printing out diary entries from Android app 【发布时间】:2021-09-24 02:52:04 【问题描述】:我有一个关于 android 日记应用的简短问题。我正在尝试实现一个功能,用户单击应用程序上的“显示条目”按钮,它会显示以前插入数据库的所有日记条目。 '
首先用户登录应用程序,用户名/密码存储在数据库中。从那里,用户可以单击“创建条目”按钮以实际输入日期/日记条目。不幸的是,这是应用程序被挂起的地方,它实际上并没有将日期和日记条目插入数据库。
具体来说,它会挂在 diaryEntry() 中的 DataBaseHelper 类中,它会尝试将值输入到表中
long result = db.insert(TABLE_NAME, null, values);
result 返回 2,因此该调用下面的条件返回 true,但两个字符串都没有输入到数据库中的 COL_4 和 COL_5 中。我一直在扯我的头发试图抓住我错过的东西,但我没有看到它。我可以借一两个大脑袋来提供一些指点吗?谢谢!
日记主页面
public class DiaryMain extends AppCompatActivity
private Button showEntries;
private DataBaseHelper myDB;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diary_main);
showEntries = findViewById(R.id.showDiaryEntriesBtn);
myDB = new DataBaseHelper(this);
public void createEntryOnClick(View view)
Intent entryClick = new Intent(this, DiaryEntry.class);
startActivity(entryClick);
public void showEntriesOnClick()
showEntries.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Cursor res = myDB.getData();
if (res.getCount() == 0)
Toast.makeText(DiaryMain.this, "No entries", Toast.LENGTH_SHORT).show();
return;
StringBuffer buffer = new StringBuffer();
while (res.moveToNext())
buffer.append("Date: " + res.getString(0) + "\n");
//buffer.append("Entry: " + res.getString(1) + "\n");
Toast.makeText(getApplicationContext(), buffer.toString(), Toast.LENGTH_LONG).show();
);
日记输入意图
public class DiaryEntry extends AppCompatActivity
EditText date, diaryEntry;
Button createBtn;
private DataBaseHelper myDB;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diary_entry);
date = findViewById(R.id.dateField);
diaryEntry = findViewById(R.id.entryField);
createBtn = findViewById(R.id.diaryEntryBtn);
myDB = new DataBaseHelper(this);
createEntry();
private void createEntry()
createBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
String passDate = date.getText().toString();
String passEntry = diaryEntry.getText().toString();
boolean var = myDB.diaryEntry(passDate, passEntry);
if (var)
Toast.makeText(DiaryEntry.this, "Entry posted!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(DiaryEntry.this, "Posting error", Toast.LENGTH_SHORT).show();
);
还有数据库助手
public class DataBaseHelper extends SQLiteOpenHelper
private static final String DATABASE_NAME = "USER_RECORD";
private static final String TABLE_NAME = "USER_DATA";
private static final String COL_1 = "ID ";
private static final String COL_2 = "USERNAME";
private static final String COL_3 = "PASSWORD";
private static final String COL_4 = "DATE";
private static final String COL_5 = "ENTRY";
public DataBaseHelper(@Nullable Context context)
super(context, DATABASE_NAME, null, 1);
@Override
public void onCreate(SQLiteDatabase db)
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, USERNAME TEXT, PASSWORD TEXT, DATE TEXT, ENTRY TEXT)");
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
db.execSQL( "DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
public boolean registerUser(String username, String password)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL_2, username);
values.put(COL_3, password);
long result = db.insert(TABLE_NAME, null, values);
if (result == -1)
return false;
else
return true;
public boolean diaryEntry(String date, String diaryText)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL_4, date);
values.put(COL_5, diaryText);
long result = db.insert(TABLE_NAME, null, values);
if (result == -1)
return false;
else
return true;
public Cursor getData()
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM USER_DATA", null);
return cursor;
编辑:阅读文档,似乎 db.insert() 将行插入到数据库中,所以我是否走在正确的轨道上,因为我需要创建一个单独的表来插入日期/日记条目对?
【问题讨论】:
应用会崩溃吗? 不,它只是回到那个主要的日记意图。调试它,我可以看到它正在将条目收集为字符串并存储局部变量,但它只是没有将它们踢到 SQLite 表中。我……想……我可能需要数据库中的两个单独的表,因为它可能会尝试将一行插入到第一行已由用户名/密码组合填充的表中。 【参考方案1】:dairyEntry
将插入用户名和密码行作为空值的数据。然而。当您问我是否会走在正确的轨道上,因为我需要创建一个单独的表来插入日期/日记条目对?然后是的。
也就是说,每个用户只需要一行(日期和条目不需要在 USER_DATA 表中),因为每个条目都会重复数据。
我建议使用 USER_DATA 表构建:-
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(ID INTEGER PRIMARY KEY, USERNAME TEXT, PASSWORD TEXT)");
AUTOINCREMENT 已删除,因为它没有必要,效率低下。
已删除 DATE 和 ENTRY 列。
然后您将拥有第二个包含 3 列的表格。 DATE 和 ENTRY 以及一个用于引用用户 ID(不是 PRIMARY 键)的 INTEGER 列。无论如何都有一个 INTEGER PRIMARY KEY 列(可能没有命名为 ID)不会有什么坏处(只是它通常是隐藏的)。
举个例子
CREATE TABLE IF NOT EXISTS diary_entry (id INTEGER PRIMARY KEY, date TEXT, entry TEXT, user_map INTEGER REFERENCES USER_DATA(id) ON DELETE CASCADE ON UPDATE CASCADE);
REFERENCES 定义了一个外键(基本上是一条规则,规定 user_map 列必须是现有用户的 id)
ON DELETE CASCADE 将在用户被删除时删除所有行(即,它级联删除,因此没有孤立的 Dairy_entry 行)
在 UPDATE 时会将所做的任何更新传递给用户的 ID(不太可能)。
所以在插入条目时,diaryEntry
方法会略有不同:-
public boolean diaryEntry(long userid, String date, String diaryText)
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL_4, date);
values.put(COL_5, diaryText);
values.put("user_map",userid);
return (db.insert(TABLE_NAME, null, values) > 0)
getAll
可能会基于如下查询:-
"SELECT diary_entry.*, USER_DATA.USERNAME, USER_DATA.PASSWORD FROM diary_entry JOIN USER_DATA ON diary_entry.user_map = USER_DATA.id;"
请注意,光标将包含列:-
id(diary_entry 行的id)
日期
条目
user_map(与用户id相同)
用户名
密码
以上代码未经编译、运行或测试,可能存在拼写错误,为原则性代码
工作示例/演示
下面通过添加一些测试数据(2 个用户和 5 个日记条目)并在 ListView 中显示日记条目,将上述内容付诸实践(即 DatabaseHelper 代码),其中包括在这种情况下单击列表项的处理它是 Toast 的一些重新分级条目的信息(日记条目的 id 和用户名)。
第一个DatabaseHelper:-
public class DataBaseHelper extends SQLiteOpenHelper
/*
Can be useful to have names available elsewhere (e.g. some are used in MainActivity)
*/
public static final String DATABASE_NAME = "USER_RECORD";
public static final String TABLE_NAME = "USER_DATA";
public static final String ENTRY_TABLE_NAME = "diary_entry";
//public static final String COL_1 = "ID "; /* Cursor Adapters MUST HAVE _id column so replaced by next line */
public static final String COL_1 = BaseColumns._ID; /* Cursor Adapter expects _id column name */
public static final String COL_2 = "USERNAME";
public static final String COL_3 = "PASSWORD";
public static final String COL_4 = "DATE";
public static final String COL_5 = "ENTRY";
public static final String COl_6 = "user_map";
private SQLiteDatabase db; // saves having to use getWritableDatabase all the time */
public DataBaseHelper(@Nullable Context context)
super(context, DATABASE_NAME, null, 1);
db = this.getWritableDatabase(); // Forces an open of the database
@Override
public void onCreate(SQLiteDatabase db)
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
COL_1 + " INTEGER PRIMARY KEY," +
COL_2 + " TEXT," +
COL_3 + " TEXT" +
")"
);
db.execSQL("CREATE TABLE IF NOT EXISTS " + ENTRY_TABLE_NAME + "(" +
COL_1 + " INTEGER PRIMARY KEY, " +
COL_4 + " TEXT, " +
COL_5 + " TEXT, " +
COl_6 + " INTEGER REFERENCES " + TABLE_NAME + "(" + /* Included for ListView */
COL_1 +
") ON DELETE CASCADE ON UPDATE CASCADE " +
")"
);
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
db.execSQL( "DROP TABLE IF EXISTS " + TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + ENTRY_TABLE_NAME); /* ADDED */
onCreate(db);
public boolean registerUser(String username, String password)
//SQLiteDatabase db = this.getWritableDatabase(); // no need now
ContentValues values = new ContentValues();
values.put(COL_2, username);
values.put(COL_3, password);
return db.insert(TABLE_NAME, null, values) > 0;
/* Simpler return used
if (result == -1)
return false;
else
return true;
*/
/*
This version returns the id of the inserted user (can be useful)
*/
public long otherReqisterUser(String userName, String password)
ContentValues values = new ContentValues();
values.put(COL_2,userName);
values.put(COL_3,password);
return db.insert(TABLE_NAME,null,values);
public boolean diaryEntry(Long userid, String date, String diaryText)
//SQLiteDatabase db = this.getWritableDatabase(); // not needed now
ContentValues values = new ContentValues();
values.put(COl_6,userid);
values.put(COL_4, date);
values.put(COL_5, diaryText);
return db.insert(ENTRY_TABLE_NAME, null, values) > 0;
/*
public Cursor getData()
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM USER_DATA", null);
return cursor;
*/
public Cursor getData()
/* rather than rawQuery query convenience method is recommended
However, this one is a little complex now due to Join
*/
/* The following is the equivalent of :-
SELECT diary_entry.*, USER_DATA.USERNAME, USER_DATA.PASSWORD
FROM diary_entry
JOIN USER_DATA ON diary_entry.user_map = USER_DATA.id
ORDER BY USER_DATA._id ASC, diary_entry.date
;
*/
return db.query(
/* Although doco says this arg is table it is actually the FROM clause so JOIN's go here*/
ENTRY_TABLE_NAME + " JOIN " + TABLE_NAME + " ON " + ENTRY_TABLE_NAME + "." + COl_6 + "=" + TABLE_NAME + "." + COL_1,
/* The columns as a String[] */
new String[]ENTRY_TABLE_NAME + ".*",TABLE_NAME + "." + COL_2, TABLE_NAME + "." + COL_3,
/* no WHERE clause, no bound parameters (?), no GROUP BY clause, no HAVING clause*/
null,null,null,null,
/* However ORDER BY clause by user then by date */
TABLE_NAME+"."+COL_1+" ASC," + ENTRY_TABLE_NAME + "." + COL_4 + " ASC"
);
还有 MainActivity :-
public class MainActivity extends AppCompatActivity
DataBaseHelper db;
Cursor csr;
SimpleCursorAdapter sca;
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = this.findViewById(R.id.diaryentries); /* List View from layout */
db = new DataBaseHelper(this);
/* Add data if none exists */
if (DatabaseUtils.queryNumEntries(db.getWritableDatabase(),DataBaseHelper.TABLE_NAME)< 1)
/* Add some testing users */
long fredsId = db.otherReqisterUser("FRED", "password");
long marysId = db.otherReqisterUser("MARY", "password");
/* Add some diary entries */
db.diaryEntry(fredsId, "2021-01-01", "Got up (Fred)");
db.diaryEntry(marysId, "2021-01-01", "Got up (Mary)");
db.diaryEntry(fredsId, "2021-01-02", "Went to work (Fred)");
db.diaryEntry(marysId, "2021-02-02", "Was sick.(Mary)");
db.diaryEntry(fredsId,"1999-01-01","Ooosps wasn't around!!!!");
DatabaseUtils.dumpCursor(csr = db.getData());
setupOrRefreshListView(); // setup the ListView
private void setupOrRefreshListView()
csr = db.getData();
if (sca == null)
sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,csr,
new String[]
DataBaseHelper.COL_4,
DataBaseHelper.COL_5
,
new int[]
android.R.id.text1,
android.R.id.text2
,
0
);
lv.setAdapter(sca);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
Toast.makeText(view.getContext(),
"You clicked on Diary Entry id = " + String.valueOf(l) +
" for " + csr.getString(csr.getColumnIndex(DataBaseHelper.COL_2)),
Toast.LENGTH_LONG)
.show();
);
else
sca.swapCursor(csr);
@Override
protected void onDestroy()
super.onDestroy();
if(!csr.isClosed())
csr.close();
希望 cmets 解释一下。
结果
应用程序运行时的样子:-
点击一个条目(Fred Got Up 被点击)并且:-
【讨论】:
绝对完美,这正是我需要阅读的内容。我会在早上试一试,因为我的头被炸了。谢谢你的好建议! @ZapRowsdower 正在使用上面的示例/演示进行工作,因此将检查代码。很快就会更新答案。 在您之前的回答之后不久,我再次愚弄了它,并实施了第二个表格,但它仍然没有将文本推送到第二个表格。我将尝试实现这些字段更改,看看我是否可以让这个东西正常工作。另外,非常感谢您缩减 getData() 函数;我试图让它只拉动所有东西,但是通过我们的 cmets,我看到了它的流程现在应该如何工作。作为旁注,有没有办法点击一个条目来编辑内容?无论如何,绝对的黄金我的朋友,再次感谢! @ZapRowsdower 添加了另一个答案,这实现了单击以编辑条目而不是 Toast。【参考方案2】:关于评论:-
顺便说一句,有没有办法点击一个条目来编辑内容?无论如何,绝对的黄金我的朋友,再次感谢!
是的,很简单。将修改 DiaryEntry 活动以根据条目的 id(将其称为 entryId)接受数据,并在编辑时更新而不是插入而不是插入新的。
无论如何,您都需要修改 DairyEntry 以确定为其创建条目的用户。但是,DatabaseHelper 也需要修改。它需要能够更新日记条目并根据 entryId 检索其他数据。
我做了一些其他的改变
因为 JOIN 将被多次使用,所以我添加了常量。 与要提取的列相同 由于 2 个 _id 列(USERDATE 和 DiaryEntry)之间存在歧义,因此 USERDATA 列被重命名(新名称为常量)所以 DatabaseHelper 现在是:-
public class DataBaseHelper extends SQLiteOpenHelper
/*
Can be useful to have names available elsewhere (e.g. some are used in MainActivity)
*/
public static final String DATABASE_NAME = "USER_RECORD";
public static final String TABLE_NAME = "USER_DATA";
public static final String ENTRY_TABLE_NAME = "diary_entry";
//public static final String COL_1 = "ID "; /* Cursor Adapters MUST HAVE _id column so replaced by next line */
public static final String COL_1 = BaseColumns._ID; /* Cursor Adapter expects _id column name */
public static final String COL_2 = "USERNAME";
public static final String COL_3 = "PASSWORD";
public static final String COL_4 = "DATE";
public static final String COL_5 = "ENTRY";
public static final String COl_6 = "user_map";
public static final String DERIVED_USERID_COLUMN = "userid"; /*<<<<< ADDED used to disambiguate column names >>>>>*/
/*<<<<< ADDED 2 constants for Join between Entry and User and for the columns >>>>>*/
private static final String ENTRYTABLE_USERTABLE_JOIN = ENTRY_TABLE_NAME + " JOIN " + TABLE_NAME + " ON " + ENTRY_TABLE_NAME + "." + COl_6 + "=" + TABLE_NAME + "." + COL_1 + " ";
private static final String[] ENTRYTABLE_USERTABLE_COLUMNS = new String[]
ENTRY_TABLE_NAME + ".*",
TABLE_NAME + "." + COL_1 + " AS " + DERIVED_USERID_COLUMN, /* give the USER _id column an alternative name using AS clause so there are not 2 _id columns */
TABLE_NAME + "." + COL_2,
TABLE_NAME + "." + COL_3
;
private SQLiteDatabase db; // saves having to use getWritableDatabase all the time */
public DataBaseHelper(@Nullable Context context)
super(context, DATABASE_NAME, null, 1);
db = this.getWritableDatabase(); // Forces an open of the database
@Override
public void onCreate(SQLiteDatabase db)
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
COL_1 + " INTEGER PRIMARY KEY," +
COL_2 + " TEXT," +
COL_3 + " TEXT" +
")"
);
db.execSQL("CREATE TABLE IF NOT EXISTS " + ENTRY_TABLE_NAME + "(" +
COL_1 + " INTEGER PRIMARY KEY, " +
COL_4 + " TEXT, " +
COL_5 + " TEXT, " +
COl_6 + " INTEGER REFERENCES " + TABLE_NAME + "(" + /* Included for ListView */
COL_1 +
") ON DELETE CASCADE ON UPDATE CASCADE " +
")"
);
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
db.execSQL( "DROP TABLE IF EXISTS " + TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + ENTRY_TABLE_NAME); /* ADDED */
onCreate(db);
public boolean registerUser(String username, String password)
//SQLiteDatabase db = this.getWritableDatabase(); // no need now
ContentValues values = new ContentValues();
values.put(COL_2, username);
values.put(COL_3, password);
return db.insert(TABLE_NAME, null, values) > 0;
/* Simpler return used
if (result == -1)
return false;
else
return true;
*/
/* This version returns the id of the inserted user (can be useful) */
public long otherReqisterUser(String userName, String password)
ContentValues values = new ContentValues();
values.put(COL_2,userName);
values.put(COL_3,password);
return db.insert(TABLE_NAME,null,values);
public boolean diaryEntry(Long userid, String date, String diaryText)
//SQLiteDatabase db = this.getWritableDatabase(); // not needed now
ContentValues values = new ContentValues();
values.put(COl_6,userid);
values.put(COL_4, date);
values.put(COL_5, diaryText);
return db.insert(ENTRY_TABLE_NAME, null, values) > 0;
/*<<<<< ADDED >>>>>*/
public long updateDiaryEntry(long entryId, String date, String entry)
ContentValues values = new ContentValues();
values.put(COL_4,date);
values.put(COL_5,entry);
return db.update(ENTRY_TABLE_NAME,values,COL_1 + "=?",new String[]String.valueOf(entryId));
/*<<<<< ADDED >>>>>*/
public Cursor getEntryById(long entryId)
return db.query(
ENTRYTABLE_USERTABLE_JOIN,
ENTRYTABLE_USERTABLE_COLUMNS,
ENTRY_TABLE_NAME + "." + COL_1 + "=?",
new String[]String.valueOf(entryId),
null,null,null
);
/*
public Cursor getData()
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM USER_DATA", null);
return cursor;
*/
public Cursor getData()
/* rather than rawQuery query convenience method is recommended
However, this one is a little complex now due to Join
*/
/* The following is the equivalent of :-
SELECT diary_entry.*, USER_DATA.USERNAME, USER_DATA.PASSWORD
FROM diary_entry
JOIN USER_DATA ON diary_entry.user_map = USER_DATA.id
ORDER BY USER_DATA._id ASC, diary_entry.date
;
*/
return db.query(
/* Although doco says this arg is table it is actually the FROM clause so JOIN's go here*/
/*ENTRY_TABLE_NAME + " JOIN " + TABLE_NAME + " ON " + ENTRY_TABLE_NAME + "." + COl_6 + "=" + TABLE_NAME + "." + COL_1*/
ENTRYTABLE_USERTABLE_JOIN, //<<<<< CHANGED to use constant as JOIN used elsewhere
/* The columns as a String[] */
ENTRYTABLE_USERTABLE_COLUMNS, //<<<<< CHANGED to use constant as columns used elsewhere
/* no WHERE clause, no bound parameters (?), no GROUP BY clause, no HAVING clause*/
null,null,null,null,
/* However ORDER BY clause by user then by date */
TABLE_NAME+"."+COL_1+" ASC," + ENTRY_TABLE_NAME + "." + COL_4 + " ASC"
);
DiaryEntry 变为:-
public class DiaryEntry extends AppCompatActivity
public static final String INTENT_EXTRA_USERID = "userid";
public static final String INTENT_EXTRA_ENTRYID = "entryid";
EditText date, diaryEntry;
Button createBtn, doneBtn;
private DataBaseHelper myDB;
private long entryId = -1, userId = -1;
private String userName, password;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diary_entry);
// Get the entryId (if editing entry else should be -1) AND
// the userId (MUST BE PROVIDED if ADDING will be retrieved when editing and Entry)
entryId = this.getIntent().getLongExtra(INTENT_EXTRA_ENTRYID,-1);
userId = this.getIntent().getLongExtra(INTENT_EXTRA_USERID,-1);
date = findViewById(R.id.dateField);
diaryEntry = findViewById(R.id.entryField);
createBtn = findViewById(R.id.diaryEntryBtn);
doneBtn = this.findViewById(R.id.done);
myDB = new DataBaseHelper(this);
// Id Entry ID provided then populate the Edit Texts
if (entryId > 0)
Cursor csr = myDB.getEntryById(entryId);
if (csr.moveToFirst())
date.setText(csr.getString(csr.getColumnIndex(DataBaseHelper.COL_4)));
diaryEntry.setText(csr.getString(csr.getColumnIndex(DataBaseHelper.COL_5)));
userId = csr.getLong(csr.getColumnIndex(DataBaseHelper.DERIVED_USERID_COLUMN));
userName = csr.getString(csr.getColumnIndex(DataBaseHelper.COL_2));
password = csr.getString(csr.getColumnIndex(DataBaseHelper.COL_3));
csr.close(); // ALWAYS close cursor when finished with them
setupButtons();
private void setupButtons()
doneBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
finish();
);
createBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
// MUST HAVE A VALID USERID IF NOT CANNOT ADD OR EDIT
if (userId < 1)
Toast.makeText(view.getContext(),"UNABLE TO PROCEED - NO KNOWN USER",Toast.LENGTH_SHORT).show();
return;
if (entryId > 0)
myDB.updateDiaryEntry(entryId,date.getText().toString(),diaryEntry.getText().toString());
else
myDB.diaryEntry(userId,date.getText().toString(),diaryEntry.getText().toString());
);
/*
private void createEntry()
createBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
String passDate = date.getText().toString();
String passEntry = diaryEntry.getText().toString();
//boolean var = myDB.diaryEntry(passDate, passEntry);
if (var)
Toast.makeText(DiaryEntry.this, "Entry posted!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(DiaryEntry.this, "Posting error", Toast.LENGTH_SHORT).show();
);
*/
我已更改布局以添加完成按钮(尽管您可以编辑应用并返回)。我使用 createButton 进行应用(添加新条目或更新)。
插入后,您可能应该清除编辑文本,但主要是显示如何单击列表进行编辑,然后返回并更新列表。
很明显 MainActivity 已经改变了,但没那么大。它不是 toasting,而是构造一个 Intent 添加一个 Extra 来传递 entryId 并启动 DiaryEntry 活动。
Main Activity 的 onResume
方法已被覆盖以刷新 ListView。
:-
public class MainActivity extends AppCompatActivity
DataBaseHelper db;
Cursor csr;
SimpleCursorAdapter sca;
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = this.findViewById(R.id.diaryentries); /* List View from layout */
db = new DataBaseHelper(this);
/* Add data if none exists */
if (DatabaseUtils.queryNumEntries(db.getWritableDatabase(),DataBaseHelper.TABLE_NAME)< 1)
/* Add some testing users */
long fredsId = db.otherReqisterUser("FRED", "password");
long marysId = db.otherReqisterUser("MARY", "password");
/* Add some diary entries */
db.diaryEntry(fredsId, "2021-01-01", "Got up (Fred)");
db.diaryEntry(marysId, "2021-01-01", "Got up (Mary)");
db.diaryEntry(fredsId, "2021-01-02", "Went to work (Fred)");
db.diaryEntry(marysId, "2021-02-02", "Was sick.(Mary)");
db.diaryEntry(fredsId,"1999-01-01","Ooosps wasn't around!!!!");
DatabaseUtils.dumpCursor(csr = db.getData());
setupOrRefreshListView(); // setup the ListView
private void setupOrRefreshListView()
csr = db.getData();
if (sca == null)
sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,csr,
new String[]
DataBaseHelper.COL_4,
DataBaseHelper.COL_5
,
new int[]
android.R.id.text1,
android.R.id.text2
,
0
);
lv.setAdapter(sca);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
/*
Toast.makeText(view.getContext(),
"You clicked on Diary Entry id = " + String.valueOf(l) +
" for " + csr.getString(csr.getColumnIndex(DataBaseHelper.COL_2)),
Toast.LENGTH_LONG)
.show();
*/
/*
Clicking item takes it to the modified DiaryEntry passing the
entryId via the Intent.
*/
Intent intent = new Intent(view.getContext(),DiaryEntry.class);
intent.putExtra(DiaryEntry.INTENT_EXTRA_ENTRYID,l);
startActivity(intent);
);
else
sca.swapCursor(csr);
@Override
protected void onResume()
super.onResume();
setupOrRefreshListView();
@Override
protected void onDestroy()
super.onDestroy();
if(!csr.isClosed())
csr.close();
结果
开始时:-
点击进入:-
将文本更改为其实我在附近,然后点击应用:-
最后点击完成:-
【讨论】:
天哪,这正是我要找的。通读修改,这比我昨天大部分时间试图偶然发现的要有意义得多。再多谢一百万,我非常感谢您提供的所有帮助。以上是关于从 Android 应用打印日记条目的主要内容,如果未能解决你的问题,请参考以下文章
Android 日记应用 - 搜索 SQLite 数据库并在 ListView 中显示结果
Android logcat:使用电子邮件从设备发送日志条目