【发布时间】:2021-01-08 06:01:38
【问题描述】:
我有一个笔记应用程序。用户可以创建新笔记或更改现有笔记。
在此应用程序中,我试图在用户更改现有笔记后立即自动保存笔记。因此,我使用textWatcher 并在文本观察者的onTextChanged() 方法中调用saveNotes() 方法。因此,我打算在每次用户从文本中添加或删除任何字符时保存注释。
var ide: Int? = null //Global Variable
//in OnCreate()
if(intent.getBooleanExtra("isViewOrUpdate", false)){
viewOrOpenedNote = intent.getSerializableExtra("note") as Note?
ide = viewOrOpenedNote?.id
在上面的两个代码示例中.. 整个想法是让变量ide 充当检查器,即如果用户正在创建新笔记,它将返回 null,否则,它将存储笔记的 id 如果用户有在现有笔记上打开以查看或编辑笔记。
下面是textWatcher
title_edit_text.addTextChangedListener((object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
saveNote() // here I
}
override fun afterTextChanged(p0: Editable?) {}
}))
saveNote()
private fun saveNote() {
val note = Note()
note.setTitle(Title)
if (ide != null) {
note.setId(ide!!) // Here I am assigning the note id to `ide` in case the
`saveNote()` is called when user has opened an existing note. If
this is a new note then ide will be null automatically.
}
class SaveNotes : AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg void: Void?): Void? {
NotesDatabase.getDatabase(applicationContext).noteDao().insertNote(note)
return null
}
override fun onPostExecute(result: Void?) {
super.onPostExecute(result)
ide = note.id //This is because: If user has added a first
character in new note, then after that an id will be
assigned to this new database, whenever
`saveNote()` method is called again after text change
I need to save the changed note to the same existing
id. I hope I am clear.
// ***UPDATE*** After much contemplation I have found out
that here lies the problem! changing the value of ide by
simply `ide = note.id` will always give null value for new
note, as this id is not received from the created note,
but from the blank note instance I created above.
}
}
SaveNotes().execute()
}
问题:即使采取了上述预防措施,每次我更改笔记时,都会创建相同笔记的多个实例。示例:
假设我输入:你好
我得到的结果是 5 个不同 id 的不同笔记。及文字如下:
h //id = 5
他 //id = 4
hel //id = 3
地狱 //id = 2
你好 //id = 1
NoteDao.java
@Dao
public interface NoteDao {
@Query("SELECT * FROM note ORDER BY id DESC")
List<Note> getAllNotes();
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertNote(Note note);
@Delete
void delete(Note note);
}
Note.java
@Entity(tableName = "note")
public class Note implements Serializable {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "title")
NoteDatabase.java
public static synchronized NotesDatabase getDatabase(Context context)
{
if(notesDatabase == null){
notesDatabase = Room.databaseBuilder(context
, NotesDatabase.class,
"note_db"
)
.addMigrations(MIGRATION_1_2)
.build();
}
return notesDatabase;
}
public abstract NoteDao noteDao();
【问题讨论】:
-
因为您每次在 onTextChanged 内部调用方法时都会插入注释。
-
你应该使用 update 方法并用它在数据库中的 id 更新笔记。
-
但我使用的是冲突策略对吗?
-
@ShahzadAfridi 即@Insert(onConflict = OnConflictStrategy.REPLACE)
-
检查下面的答案。
标签: java android database kotlin android-room