【发布时间】:2019-11-10 16:45:36
【问题描述】:
我有一个正常工作的 CardView 项目的 RecyclerView 列表。在创建插入数据库的新 CardView 后,我想触发一个 Toast,通知用户 CardView 已成功添加并显示 CardView 编号。 CardView 编号是插入数据库的 CardView 项的 Id。当用户单击触发 onClickSave() 的保存按钮时,数据将保存到数据库中。
我在 Dao 中设置了一个@Query 来获取 MAX(cardId):
Dao
...
@Query("SELECT MAX(cardId) FROM cards")
LiveData<Integer> getMax();
@Insert
void insertCard(Card card);
问题是两个 Toast 正在触发。第一个 Toast 正在返回之前创建的 CardView 编号和,然后第二个 Toast 正在触发并显示刚刚添加的最新 CardView 编号。例如,Toast 将显示 CardView 编号 33,然后触发第二个 Toast,显示刚刚创建的预期 CardView 编号 34(我确认 CardViews 33 和 34 都在数据库中和两个最高的项目中,使用 DB Browser for SQLite 软件)。
AddorUpdateCardActivity
...
private int newMax = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(cardViewModel.class);
}
public void onClickSave(View v) {
// set card data
// then insert data in database
mViewModel.insertCard(card1);
mViewModel.getMax().observe(this, value -> { newMax = value; Toast.makeText(AddorUpdateCardActivity.this, "card #" + newMax + " was saved to the list", Toast.LENGTH_LONG).show();});
}
ViewModel
...
public cardViewModel(Application application) {
super(application);
repository = new cardRepository(application);
getMax = repository.getMax();
}
public LiveData<Integer> getMax() {
return getMax;
}
public void insertCard(Card card) {
repository.insertCard(card);
}
cardRepository
private CardDao cardDao;
private LiveData<Integer> getMax;
public cardRepository(Application application) {
RoomDatabase db = RoomDatabase.getDatabase(application);
cardDao = db.cardDao();
}
public LiveData<Integer> getMax() {
return cardDao.getMax;
}
public void insertCard(Quickcard newcard) {
AsyncTask.execute(() -> cardDao.insertCard(newcard));
}
我在这里缺少什么?如果卡片正确插入数据库,那么为什么 ViewModel 观察者不只返回这个新的 CardView 编号而不是两个 Toast?
作为参考,我展示了在 Room 和 ViewModel 之前使用的先前代码,它使用光标来获取最新和最高插入的 Id:
public class SQLiteDB extends SQLiteOpenHelper {
...
public int getLastInsertId() {
int index = 0;
SQLiteDatabase sdb = getReadableDatabase();
Cursor cursor = sdb.query(
"sqlite_sequence",
new String[]{"seq"},
"name = ?",
new String[]{TABLE_NAME},
null,
null,
null,
null
);
sdb.beginTransaction();
try {
if (cursor !=null) {
if (cursor.moveToLast()) {
index = cursor.getInt(cursor.getColumnIndex("seq"));
}
}
...
}
return index;
}
【问题讨论】:
-
没有`mViewModel.insertCard(card1); `
ViewModel中的方法。分享那部分代码。 -
@GensaGames 会在美国东部时间下午 6 点之前完成。
-
@GensaGames ViewModel 的 insertCard() 已更新。 Repository 和 Dao 也是如此。
-
你能把Toast移到
mViewModel.getMax().observe()里面吗?您的 Toast 可能会在数据保存和newMax值更新之前触发。 @AJW -
@Prokash Sarkar 我明白你的意思,但我不知道如何将 Toast 移到里面。你能举个例子吗?
标签: android android-room android-viewmodel