savedRecordFileName is a variable of LivaData<String>, I hope to get the value of savedRecordFileName at once in Code A.
You know that LiveData variable is lazy, maybe the value of savedRecordFileName is null in binding.btnStop.setOnClickListener { }, so the code in binding.btnStop.setOnClickListener { } will not be fired when the value of savedRecordFileName is null.
I hope that the code in binding.btnStop.setOnClickListener { } can always be fired, how can I do?
BTW, I think the Code B is not suitable because the value of savedRecordFileName maybe changed by other function.
Code B
binding.btnStop.setOnClickListener {
mHomeViewModel.savedRecordFileName.observe(viewLifecycleOwner){
val aMVoice = getDefaultMVoice(mContext,it)
mHomeViewModel.add(aMVoice)
}
}
Code A
class FragmentHome : Fragment() {
private val mHomeViewModel by lazy {
getViewModel {
HomeViewModel(mActivity.application, provideRepository(mContext))
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
...
binding.btnStop.setOnClickListener {
mHomeViewModel.savedRecordFileName.value?.let{
val aMVoice = getDefaultMVoice(mContext,it)
mHomeViewModel.add(aMVoice)
}
}
...
return binding.root
}
}
class HomeViewModel(val mApplication: Application, private val mDBVoiceRepository: DBVoiceRepository) : AndroidViewModel(mApplication) {
val savedRecordFileName: LiveData<String> = mDBVoiceRepository.getTotalOfVoice().map {
mApplication.getString(R.string.defaultName, (it+1).toString())
}
}
class DBVoiceRepository private constructor(private val mDBVoiceDao: DBVoiceDao){
fun getTotalOfVoice() = mDBVoiceDao.getTotalOfVoice()
}
@Dao
interface DBVoiceDao{
@Query("SELECT count(id) FROM voice_table")
fun getTotalOfVoice(): LiveData<Long>
}
Add Content
To Ridcully: Thanks!
I think your way "move all of that into the viewmodel class" is good !
I think it will be OK even if the filename is livedata in your Code C, right?
Code C
viewModelScope.launch(Dispatchers.IO) {
filename = dao.getFilename() // without livedata. I think it will be OK even if the filename is livedata
voice = getDefaultVoice(...) // also do this in background
add(voice)
result.postValue(true)
}