iT邦幫忙

0

Android MVVM ViewModel問題

  • 分享至 

  • xImage

大家好~我是程式新手,想詢問遇到的問題

我在網站中找到有關於 MVVM 使用 api 的相關範例
https://givemepass.blogspot.com/2019/11/android-mvvm-koin.html?fbclid=IwAR15W9Zzd8GCojBJgK9aIoqWn5k55Zv-9boiujT2BIGyQFwvEmTkKBgfnic

範例中,將api設置為viewmodel並在activity中observe所獲取到的資料

class InfoViewModel(var infoRepository: InfoRepository) : ViewModel() {
    private var userInfoLiveData = MutableLiveData<String>()
    val loading = MutableLiveData<Boolean>()

    fun getUserInfo(): LiveData<String> = userInfoLiveData

    @SuppressLint("CheckResult")
    fun callInfo() {
        val result = StringBuffer()
        infoRepository.loadInfo()
            .subscribeOn(Schedulers.newThread())
            .map {
                val sb = StringBuffer()
                it.forEach { post ->
                    sb.append(post.body)
                    sb.append("\n")
                    sb.append("---------------------\n")
                }
                result.append(sb.toString())
            }
            .observeOn(AndroidSchedulers.mainThread())
            .compose(toggleLoading())
            .subscribe({
                userInfoLiveData.setValue(it.toString())
            }, {
                userInfoLiveData.setValue(result.toString())
            })
    }

    private fun <T> toggleLoading(): SingleTransformer<T, T> {
        return SingleTransformer { single ->
            single
                .doOnSubscribe { loading.value = true }
                .doFinally { loading.value = false }
        }
    }

}

我有個疑問~
當我使用databinding的方式,將button的onclick設置在viewmodel中

            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="@{() -> viewModel.goBackClicked()}"
                android:textSize="16sp" />

我在該activity對應的viewModel中,要使用api viewmodel

class ActivityViewModel(private val infoViewModel: InfoViewModel) : ViewModel() {
    fun conFirmClicked() {
        infoViewModel. callInfo()
    }
}
val myModule = module {
    viewModel { InfoViewModel(get()) }
    viewModel { ActivityViewModel(get()) }
}

但這樣不就違反了viewmodel單一職責原則
想了解當遇到這種情況時該如何解決~

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
waynehe1221
iT邦新手 5 級 ‧ 2024-07-11 09:40:04

Hi~
我認為你提出的問題的範圍有點廣,應該更完整的去提出你認為哪個區塊是違反單一職責原則。
另外,我個人認為在 Android 開發的框架下,其實有很多時候你在產出時要顧及這些原則的難度是更高的,建議不需要 100% 符合所有原則,但是大方向要維持。
譬如: 這個情況下你維持 ViewModel 單一職責的目的是甚麼? 我想大多數目標是想要把商業邏輯視為 ViewModel 的職責,那在維持這個大方向的前提下,如果有數據是需要散落在 View 或是其他區塊,我認為就不是開發主要關注的。
當然,如果他是個問題,未來可能會被放大,但是我認為在有這些想法時,不要執著在完美符合,而是先從大方向完善,未來隨著經驗增加,你就有更多想法來完善這些問題,到時候也很可能這對你來說根本不是問題。


回到問題本身,我看到的是:
InfoViewModel 被創建後,又被放入 ActivityViewModel,然後你的實際按鈕行為又放入 ActivityViewModel。
如果你想做的是

  • InfoViewModel 定義為傳輸 API 資料的 VM
  • ActivityViewModel 定義為實作 Activity 行為的 VM

以這兩點來看,並不違反單一職責。


如果有興趣的話,可以看一下 Android 官方目前對於架構的專案,或許會有意外的收穫,不用執著在用了甚麼套件,先有一套對 MVVM 的理解,在慢慢隨著經驗調整就好。
供參: https://github.com/android/architecture-samples

我要發表回答

立即登入回答