简体   繁体   English

Kotlin & Room:从插入的返回 ID 不起作用

[英]Kotlin & Room: return id from inserted not working

I want to get the id from de newly inserted data on database.我想从数据库中新插入的数据中获取 id。 I'm using Room and Kotlin.我正在使用 Room 和 Kotlin。 I've already tried a lot of solutions that I found here on StackOverFlow, but I couldn't achieve this.我已经尝试了很多我在 StackOverFlow 上找到的解决方案,但我无法做到这一点。

Here's my code:这是我的代码:

Dao (AvaliacaoDao.kt)道 (AvaliacaoDao.kt)

interface AvaliacaoDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun addAvaliacao(avaliacao: Avaliacao) : Long
... 
}

Repository (AvaliacaoRepository.kt)存储库 (AvaliacaoRepository.kt)

class AvaliacaoRepository(private val avaliacaoDao: AvaliacaoDao) {

    suspend fun addAvaliacao(avaliacao: Avaliacao) : Long {
        val longId = avaliacaoDao.addAvaliacao(avaliacao)
        Log.d("AvaliacaoRepository", longId.toString())
        return longId
    }
... 
}

ViewModel (AvaliacaoViewModel.kt) ViewModel (AvaliacaoViewModel.kt)

class AvaliacaoViewModel(application: Application): AndroidViewModel(application) {

    var returnedVal: MutableLiveData<Long> = MutableLiveData()

    fun addAvaliacao(avaliacao: Avaliacao) {
        viewModelScope.launch(Dispatchers.IO) {
            val resultRepo = repository.addAvaliacao(avaliacao)
            returnedVal.postValue(resultRepo)
            Log.d("AvaliacaoViewModel", "Avaliação id: $resultRepo")
        }
    }
... 
}

Fragment (AddAvaliacaoFragment.kt)片段 (AddAvaliacaoFragment.kt)

class AddAvaliacaoFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        insertDataToDatabase()
    }

    private fun insertDataToDatabase(){
        val dataCriacao = binding.dataCriacaoAvaliacaoEditText.text.toString()
        val nomeAvaliacao = binding.nomeAvaliacaoEditText.text.toString()
        Log.d(TAG, "dataCriacao: $dataCriacao, nome avaliação: $nomeAvaliacao")

        if(inputCheck(dataCriacao, nomeAvaliacao)){
            // Criar objeto Avaliação
            val avaliacao: Avaliacao = Avaliacao(
                0,
                nomeAvaliacao,
                dataCriacao,
                0f,
                0f,
                0,
                0,
                0
            )

            // Adicionar dados ao Banco de Dados
            mAvaliacaoViewModel.addAvaliacao(avaliacao)

            mAvaliacaoViewModel.returnedVal.observe(viewLifecycleOwner, Observer {
                Log.d(TAG, "Observer Avaliação ID: $it")
            })

            Toast.makeText(requireContext(), getString(R.string.avaliacao_add_sucesso), Toast.LENGTH_SHORT).show()

            // Navegar de volta pra lista de Avaliações
            findNavController().navigate(R.id.action_addAvaliacaoFragment_to_navigation_avaliacoes)

        } else {

            Toast.makeText(requireContext(), getString(R.string.avaliacao_add_erro), Toast.LENGTH_SHORT).show()
        }
    }

    private fun inputCheck(dataCriacao: String, nomeAvaliacao: String): Boolean{
        return !(TextUtils.isEmpty(dataCriacao) && TextUtils.isEmpty(nomeAvaliacao)
                && TextUtils.equals(dataCriacao, "") && TextUtils.equals(nomeAvaliacao, ""))
    }

}

Gradle Gradle

implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0-rc03"

def room_version = "2.2.6"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"

At console, I get the log from repository and viewModel, but the returnedVal observer at fragment don't work and I can't get the returned id from inserted data.在控制台,我从存储库和 viewModel 中获取日志,但是片段中的 returnedVal 观察者不起作用,我无法从插入的数据中获取返回的 id。

Can anyone help me, please?任何人都可以帮助我吗?

Bind your view model after onViewCreated在 onViewCreated 之后绑定您的视图 model

class AddAvaliacaoFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        bindViewModel()
        insertDataToDatabase()
    }

    private fun bindViewModel() {
       mAvaliacaoViewModel.returnedVal.observe(viewLifecycleOwner, Observer {
           // Navegar de volta pra lista de Avaliações
            findNavController().navigate(R.id.action_addAvaliacaoFragment_to_navigation_avaliacoes)     
       })
    }

    private fun insertDataToDatabase(){
        val dataCriacao = binding.dataCriacaoAvaliacaoEditText.text.toString()
        val nomeAvaliacao = binding.nomeAvaliacaoEditText.text.toString()
        Log.d(TAG, "dataCriacao: $dataCriacao, nome avaliação: $nomeAvaliacao")

        if(inputCheck(dataCriacao, nomeAvaliacao)){
            // Criar objeto Avaliação
            val avaliacao: Avaliacao = Avaliacao(
                0,
                nomeAvaliacao,
                dataCriacao,
                0f,
                0f,
                0,
                0,
                0
            )

            // Adicionar dados ao Banco de Dados
            mAvaliacaoViewModel.addAvaliacao(avaliacao)

            

            Toast.makeText(requireContext(), getString(R.string.avaliacao_add_sucesso), Toast.LENGTH_SHORT).show()

            

        } else {

            Toast.makeText(requireContext(), getString(R.string.avaliacao_add_erro), Toast.LENGTH_SHORT).show()
        }
    }

    private fun inputCheck(dataCriacao: String, nomeAvaliacao: String): Boolean{
        return !(TextUtils.isEmpty(dataCriacao) && TextUtils.isEmpty(nomeAvaliacao)
                && TextUtils.equals(dataCriacao, "") && TextUtils.equals(nomeAvaliacao, ""))
    }

}

For Handling Event only once you can use SingleLiveEvent or you can check this article仅用于处理事件一次,您可以使用 SingleLiveEvent 或者您可以查看这篇文章

https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150 https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM