Use viewLifecycleOwner como LifecycleOwner

17

Tengo un fragmento:

class MyFragment : BaseFragment() {

   // my StudentsViewModel instance
   lateinit var viewModel: StudentsViewModel

   override fun onCreateView(...){
        ...
   }

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

       viewModel = ViewModelProviders.of(this).get(StudentsViewModel::class.java)
       updateStudentList()
   }

   fun updateStudentList() {
        // Compiler error on 'this': Use viewLifecycleOwner as the LifecycleOwner
        viewModel.students.observe(this, Observer {
            //TODO: populate recycler view
        })
    }
}

En mi fragmento, tengo una instancia de StudentsViewModel que se inicia en onViewCreated(...) .

En, StudentsViewModel, studentses un LiveData:

class StudentsViewModel : ViewModel() {
    val students = liveData(Dispatchers.IO) {
          ...
    }
}

Volver a MyFragment, en función de updateStudentList()recibo compilador de error que se queja el thisparámetro pasé para .observe(this, Observer{...})queUse viewLifecycleOwner as the LifecycleOwner

¿Por qué me sale este error? Cómo deshacerse de él?

user842225
fuente

Respuestas:

34

¿Por qué me sale este error?

Lint recomienda que utilice el ciclo de vida de las vistas del fragmento ( viewLifecycleOwner) en lugar del ciclo de vida del fragmento en sí ( this). Ian Lake y Jeremy Woods de Google analizan la diferencia como parte de esta presentación de Android Developer Summit , e Ibrahim Yilmaz cubre las diferencias en esta publicación de Medium .

  • viewLifecycleOwnerestá vinculado a cuando el fragmento tiene (y pierde) su interfaz de usuario ( onCreateView(), onDestroyView())

  • thisestá vinculado al ciclo de vida general del fragmento ( onCreate(), onDestroy()), que puede ser sustancialmente más largo

Cómo deshacerse de él?

Reemplazar:

viewModel.students.observe(this, Observer {
        //TODO: populate recycler view
    })

con:

viewModel.students.observe(viewLifecycleOwner, Observer {
        //TODO: populate recycler view
    })

En su código actual, si onDestroyView()se llama, pero onDestroy()no es así, continuará observando el LiveData, tal vez bloqueado, cuando intente llenar un no existente RecyclerView. Al usarlo viewLifecycleOwner, evitas ese riesgo.

CommonsWare
fuente
66
Tenga en cuenta que aún debe usar "this" en el caso de DialogFragment (y probablemente cada fragmento que no devuelva una vista para onCreateView. De lo contrario, obtendrá una excepción:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
desarrollador de Android
@androiddeveloper ¿Aún podría usar lifeCycleOwner en onViewCreated y en adelante?
jontro
@ jontro Estoy bastante seguro de que puedes. Pruébalo y avísame :)
desarrollador de Android
¡@androiddeveloper parece funcionar bien!
jontro
1

En lugar de thisusar viewLifecycleOwnerpara observarLiveData

viewModel.students.observe(viewLifecycleOwner, Observer {
    //TODO: populate recycler view
})
Md. Asaduzzaman
fuente