【问题标题】:Updating a note after it was just created在刚刚创建后更新笔记
【发布时间】:2020-04-26 08:18:33
【问题描述】:

我目前正在开发一个遵循 MVVM 架构的笔记应用程序。有2个活动。主要带有笔记列表和允许用户查看笔记的查看模式。如果他们单击描述或标题,则允许编辑模式,您可以在其中保存更改以及不保存更改。创建新笔记时,它会将用户带到相同的活动以查看/编辑笔记,并启用带有空标题和描述的编辑模式。我目前遇到的问题是,如果用户创建了一个便笺并决定在创建后立即对其进行编辑,那么当用户返回到便笺列表时,它会有一堆便笺,每个便笺都包含他所做的每个更新,因此笔记被保存到新笔记中,而不是更新现有笔记。

保存笔记代码:

private void saveNote(){

        //updates existing note. Next Statement adds new note
        if(getIntent().hasExtra(EXTRA_ID)){
            mViewTitle.setText(mEditTitle.getText().toString());
            String timeStamp = Utility.getCurrentTimestamp();
            timeStamp = timeStamp.replace("-", " ");

            Note note = new Note(mTitle, mContent, timeStamp);
            note.setId(mID);
            mAddEditNoteViewModel.update(note);
            Toast.makeText(this, "Note Updated", Toast.LENGTH_SHORT).show();
        } else if(!getIntent().hasExtra(EXTRA_ID)){
            mViewTitle.setText(mEditTitle.getText().toString());
            String timeStamp = Utility.getCurrentTimestamp();
            timeStamp = timeStamp.replace("-", " ");

            Note note = new Note(mTitle, mContent, timeStamp);
            mAddEditNoteViewModel.insert(note);
            Toast.makeText(this, "New Note Created:", Toast.LENGTH_SHORT).show();
        }
    }

如您所见,我检查是否需要更新或创建新笔记的方法是检查意图是否具有我需要的数据(在本例中为 ID)。但是当用户刚刚创建笔记并且没有返回主活动时,每次新创建的笔记被更新而不返回主活动时都会调用 else if 语句从而创建一个新笔记。我似乎找不到解决这个问题的方法。我想只在用户返回主活动后保存新笔记,但如果用户创建笔记,单击复选标记图标(保存)并关闭应用程序而不返回主活动,则笔记将不会保存。我该如何解决这个问题?

【问题讨论】:

    标签: java android mvvm viewmodel android-livedata


    【解决方案1】:

    通过执行以下操作,我能够得到我想要的结果:

    在我的存储库中,我使用 get 方法返回一个 long,该方法返回在 asynctask 的 doInBackground 方法中返回的 id,这与之前不同(在插入的结果交付后,后台执行操作(null))结果直到 doInBackground 运行才交付:

     public Long insert(Note note) {
            try {
                Long id = new InsertNoteAsyncTask(mNoteDao).execute(note).get();
                Log.d(TAG, "insert: CALLED - REPOSITORY - LONG: " + id);
                return id;
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
    

    然后视图模型只是获取并返回 long

    public Long insert(Note note) {
        return mNoteRepository.insert(note);
    }
    

    一切都按预期进行。非常感谢@Tenfour04 的帮助

    【讨论】:

      【解决方案2】:

      如果我理解正确,您正在使用EXTRA_ID 的存在来确定当前正在编辑的注释是否已经存在。

      但是EXTRA_ID 的存在真正意味着Activity 是使用加载现有ID 的指令打开的。

      所以这不是两个等效的含义,您不应该使用EXTRA_ID 作为您是否保存新笔记的测试。

      有很多方法可以解决这个问题。我要做的是将mID 更改为mSavedNoteId 并将其设为可为空的IntegerLong 而不是intlong。 (不确定您使用的是哪个。)让 null 值表示您没有使用已保存的笔记。当活动打开时,您可以根据额外分配mSavedNoteId的值,如果没有额外,则保留为null。仅在首次保存时创建 ID 号并将其分配给 mSavedNoteId。最后,您的 if 语句可以检查 mSavedNoteId 是否为空,以确定是保存新笔记还是更新现有笔记。

      private void saveNote() {
          mViewTitle.setText(mEditTitle.getText().toString());
          String timeStamp = Utility.getCurrentTimestamp().replace("-", " ");
          Note note = new Note(mTitle, mContent, timeStamp);
          if (mSavedNoteId != null){
              note.setId(mSavedNoteId);
              mAddEditNoteViewModel.update(note);
              Toast.makeText(this, "Note Updated", Toast.LENGTH_SHORT).show();
          } else {
              mSavedNoteId = generateNewNoteId(); // however you're doing it
              note.setId(mSavedNoteId);
              mAddEditNoteViewModel.insert(note);
              Toast.makeText(this, "Note Updated", Toast.LENGTH_SHORT).show();
          } 
      }
      

      我想也许是您的视图模型实现在您调用insert() 时生成了一个 ID。在这种情况下,让insert() 返回生成的 ID 并像这样更改 else 分支:

      mSavedNoteId = mAddEditNoteViewModel.insert(note);
      Toast.makeText(this, "Note Updated", Toast.LENGTH_SHORT).show();
      

      【讨论】:

      • 我这样做了,但我有一个问题。我使用带有自动生成 ID 的房间数据库。我将插入接口从 void 更改为 Long 并检索了插入异步任务的值。现在的问题是,当应用程序首次启动并且我创建一个便笺时,它会说它是使用 ID 0 创建的,但实际上不是,所以当我更新它时它显示它确实更新了,但是一旦你返回它就没有。在该 id 创建另一个之后,id 会说 5,然后我回到主要活动并再次单击,但 id 确实是 6
      • 我不是Room用户,但听起来您并没有等待ID的返回值。由于它是异步的,因此您需要能够将回调传递给视图模型的 insert 方法。所以当你调用insert时,你应该锁定编辑按钮(使用一个布尔值来保护其点击监听的内容),然后回调可以为你设置mSavedNoteId并解锁编辑按钮。
      • 小心使用 AsyncTask。它将在下一个 Android release 中被弃用。它可能会正常工作,但未来的示例可能不会包含它。
      • 是的,我就是这么想的。当我回到家并研究下一个版本时,我将采用这种方式。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-09
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      相关资源
      最近更新 更多