[Android jetpack 소개] [Android jetpack room 예제 : Todo - (1)] Android jetpack room 을 활용하여 할일(Todo) 예제를 확인해보았는데요 이번에는 jetpack ViewModel 및  Li...

[안드로이드] Android jetpack ViewModel-LiveData 예제 : Todo - (2)

 


[Android jetpack 소개]

[Android jetpack room 예제 : Todo - (1)]

Android jetpack room 을 활용하여 할일(Todo) 예제를 확인해보았는데요

이번에는 jetpack ViewModel 및 LiveData 에 대해서 알아보고,

Todo 예제를 이어서 jetpack ViewModel-LiveData 을 적용하려고합니다.





1. jetpack ViewModel

ViewModel 클래스는 수명 주기를 고려하여 UI 관련 데이터를 저장하고 관리하도록 설계되었습니다. 

UI 관련 데이터를 저장하고 관리한다는 건 바로 알겠는데 수명 주기를 고려한다는 것은 조금 더 알아보겠습니다.

아래 그림은 activity가 생성된 후 회전 시키고 종료 될 때까지의 수명주기 상태를 보여줍니다



Activity 회전될 때 re-onCreate 과정에서 ViewModel Scope 는 계속 유지가 되고 App 이 종료되서야 clear 되는 것을 볼 수 있습니다.

그렇다면 수명주기를 고려한다는 것은 액티비티가 중간에 재생성되는 것에 개의치 않고 보존된다. 

즉, 기존에 보관되있던 View 관련 데이터를 계속해서 사용할 수 있다는 것을 의미합니다.







2. jetpack LiveData

Observer에게 데이터 변경에 대한 알림을 보내는 클래스입니다.

계속해서 데이터를 관찰하고 업데이트되기 때문에 UI 와 데이터간에 일치성을 가진다는 장점을 가지고 있습니다.







3. jetpack ViewModel-LiveData 활용


이전에 사용했던 Todo 예제를 계속해서 이어가려고 합니다.

중간중간 생략되는 부분들도 있을거라서 소스를 받고 함께 보는걸 추천드립니다:)

다운로드


아래 두가지 포인트를 가지고 시작해봅시다.

 - room 의 데이터베이스를 ViewModel 에서 관리하게 할 것

 - room 에 저장되는 데이터(List<Todo>) 를 LiveData 로 처리



♣ ViewModel

데이터를 보관하고 관리하기 위한 class MainViewModel 를 만들고 todoDataBase 를 보관해줍니다. View 에서는 getDao() 를 통해 room 에 접근 할 수 있을 것입니다.

class MainViewModel(application: Application) : AndroidViewModel(application) {

private var todoDataBase = TodoDataBase.getInstance(application)

fun getDao(): TodoDao? {
return todoDataBase?.todoDao()
}
}


MainActivity 에 MainViewModel 을 사용하기 위해 아래와 같이 불러올 수 있습니다.

// Load mainViewModel
val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]




♣ LiveData

기존에 사용하였던 List<Todo> 를 LiveData 로 변경해줍니다.

@Query("SELECT * FROM todo")
fun getAll(): LiveData<List<Todo>>


아래와 같이 LiveData 객체와 Observer 객체를 연결해주고, 데이터 변경에 따른 동작을 정의해줍니다.

mainViewModel.getDao()?.getAll()?.observe(this, Observer {
todoAdapter = TodoAdapter(ArrayList(it), mainViewModel)
rvResult.adapter = todoAdapter
})




♣ MainActivity 전체소스

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Load mainViewModel
val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]

// UI Initialize
val etTodo = findViewById<EditText>(R.id.etTodo)
val btnAdd = findViewById<Button>(R.id.btnAdd)
val rvResult = findViewById<RecyclerView>(R.id.rvResult)
val btnDeleteAll = findViewById<Button>(R.id.btnDeleteAll)
val btnDelete = findViewById<Button>(R.id.btnDelete)
var todoAdapter = TodoAdapter(ArrayList(), mainViewModel)
val viewManager = LinearLayoutManager(this)

rvResult.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = todoAdapter
}

// Use LiveData-ViewModel
mainViewModel.getDao()?.getAll()?.observe(this, Observer {
todoAdapter = TodoAdapter(ArrayList(it), mainViewModel)
rvResult.adapter = todoAdapter
})

// UI Listener
btnAdd.setOnClickListener {
if (etTodo.text.toString().isNotEmpty()) {
val todo = Todo(etTodo.text.toString(), false)
mainViewModel.getDao()?.insert(todo)
etTodo.setText("")
}
}

btnDeleteAll.setOnClickListener {
mainViewModel.getDao()?.deleteAll()
}

btnDelete.setOnClickListener {
val todo = todoAdapter.getSelectedItem()
todo?.run {
mainViewModel.getDao()?.delete(this)
}
}
}
}




참고자료

https://developer.android.com/topic/libraries/architecture/viewmodel

https://developer.android.com/topic/libraries/architecture/livedata


0 comments: