Запуск фрагмента в модели представления - PullRequest
0 голосов
/ 03 февраля 2020

Я пытаюсь переделать свой учебный проект, чтобы использовать MVVM и привязку данных.

Проект находится здесь: https://github.com/Sophon/CriminalIntent/tree/dev

Перед переделкой приложение ведет себя так:

  • MainActivity содержит CrimeListFragment, то есть RecyclerView из Crime с
  • CrimeHolder реализует View.OnClickListener и onClick () использует функцию обратного вызова с id из Crime нажали
  • MainActivity реализует функцию обратного вызова и запускает спецификацию c (идентифицируется как id) CrimeDetailFragment с использованием supportFragmentManager
  • это поведение можно увидеть в ветке Master.

Теперь, при переработке, это то, что у меня есть до сих пор:

  • list_item.xml использует привязку данных
  • CrimeViewModel имеет свойство crime: Crime
  • Я раздуваю привязку в CrimeListFragment 's onCreateView()
  • CrimeHolder класс имеет init { binding.viewModel = CrimeViewModel() }
  • CrimeHolder также имеет bind(crime: Crime) и там я присваиваю crime viewModel * crime
  • CrimeListAdapter класс само за себя
  • это будет в связанной ветке видится поведение dev

Каждое преступление в RecyclerView является кликабельным, то есть list_item.xml будет иметь android:onClick="@{() -> viewModel.onCrimeClicked()}", а CrimeViewModel будет иметь функцию onCrimeClicked().

Мой вопрос: Как запустить новый фрагмент (CrimeDetailFragment) из onClicked() модели представления при соблюдении архитектуры MVVM?

I можно просто реализовать View.OnClickListener в Держателе , как и раньше, но с MVVM мне следует избегать logi c в View s (CrimeListFragment в моем случае) .

Бонусный вопрос - какие еще изменения я должен внести, чтобы больше MVVM?

1 Ответ

1 голос
/ 03 февраля 2020

IMO ,, я бы создал лямбда-блок внутри Activity или Fragment, и я бы передал лямбда-блок адаптеру примерно так:

private val onCrimeClicked: (Crime) -> Unit = {
    // This will be triggered later
}
private val crimeListAdapter = CrimeListAdapter(onCrimeClicked)

Внутри адаптера вы передаете тот же лямбда-блок конструктору CrimeHolder где вы создаете новый CrimeHolder внутри onCreateViewHolder ().

Тогда ваш класс CrimeHolder может выглядеть следующим образом:

class CrimeHolder(private val onCrimeClicked: (Crime) -> Unit = {}){

    fun bind(crime : Crime){
        list.setOnClickListener{
            onCrimeClicked(crime)
        }
    }
}

Посмотрите, подходит ли вам это!

PS: Таким образом, вы не нарушаете правило MVVM.

...