Как переместить логи c в ViewModel? - PullRequest
0 голосов
/ 30 марта 2020

Как мне переместить логи c из фрагмента в моей ViewModel?

override fun onItemClick(titleName: Int) {
    when (titleName) {
        R.string.about_terms_service -> {
            activity?.addFragment(
                WebViewFragment.newInstance(
                    TERMS_LINK,
                    getString(R.string.about_terms_service)
                )
            )
        }
        R.string.about_open_source_licenses -> activity?.addFragment(LicensesFragment())
    }
}

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Этот лог c может быть перемещен в ViewModel, но с небольшими затратами. Конечно, решение о том, какой фрагмент добавить, следует переместить в ViewModel, но код добавляемого фрагмента должен остаться в Fragment (или Activity). Я думаю, это должно выглядеть примерно так:

Фрагмент:

override fun onItemClick(titleName: Int) {
    viewModel.onTitleClick(titleName)
}

ViewModel :

fun onTitleClick(titleName: Int) {
    when (titleName) {
        R.string.about_terms_service -> {
            postViewModelEvent(ShowWebViewFragmentEvent())
        }
        R.string.about_open_source_licenses -> {
            // TODO: open License fragment
        }
    }
}

In ViewModel вы должны заменить эти // TODO s указанными c командами для вашего Представления (Fragment, Activity), что приведет к переходу к указанному c фрагменту. О том, как это сделать, например, написано здесь (но, конечно, подойдет любое ViewModel - Fragment решение).

В этом случае это лог c может быть легко протестировано.

Если вы подключаете ваш ViewModel к вашему Fragment посредством просмотра событий модели (описанных в ссылке), вы можете сделать это:

Создать событие показа WebViewFragment, например:

class ShowWebViewFragmentEvent(): ViewModelEvent {
    override fun handle(activity: BaseActivity) {
        super.handle(activity)
        activity?.addFragment(
                WebViewFragment.newInstance(
                    TERMS_LINK,
                    getString(R.string.about_terms_service)
                )
            )
    }
}

и размещение его в вашем ViewModel (вместо первого // TODO), например:

postViewModelEvent(ShowWebViewFragmentEvent())

Обратите внимание , что все необходимые изменения из связанного поста должны быть сделаны.

0 голосов
/ 06 апреля 2020

Спасибо за совет , но я изменил это решение следующим кодом:

Фрагмент:

override fun onItemClick(titleName: Int) {
    viewModel.onTitleClick(titleName)
}

ViewModel:

fun onTitleClick(titleName: Int) {
        when (titleName) {
            R.string.about_terms_service -> {
                termsOfServiceItemClickEvent.postValue(
                    ViewModelEvent(
                        WebViewFragment.newBundle(
                            url = TERMS_LINK,
                            title = appContext.getString(R.string.about_terms_service)
                        )
                    )
                )
            }
            R.string.about_open_source_licenses -> licenseItemClickEvent.postValue(ViewModelEvent(R.string.about_open_source_licenses))
        }
    }

ViewModelEvent:

open class ViewModelEvent<out T>(private val content: T? = null) {

    var hasBeenHandled = false
        private set

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }
}

И снова фрагмент:

viewModel = ViewModelProviders
    .of(this, viewModelFactory)
    .get(AboutViewModel::class.java)

viewModel.licenseItemClickEvent.observe(this, Observer<ViewModelEvent<Int>> {
    it?.getContentIfNotHandled()?.let { activity?.addFragment(LicensesFragment()) }
})
viewModel.termsOfServiceItemClickEvent.observe(this, Observer<ViewModelEvent<Bundle>> {
    it?.getContentIfNotHandled()?.let { args ->
        activity?.addFragment(WebViewFragment.newInstance(args = args))
    }
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...