[Android] 옵저버 패턴을 이용한 view 갱신 + 개발일지

 

[옵저버(Observe)] 

 

옵저버는 데이터나 어떤 이벤트를 관찰하여 미리 정의해둔 어떠한 동작을 즉각 수행하는 프로그래밍 패턴이다.

 

ex>  A라는 버튼이 클릭되거나 B라는 인스턴스가 변할 때 view를 즉각적으로 변화시키는 동작

 

옵저버 패턴을 활용하면 다른 객체의 상태 변화를 특별한 호출 없이 즉각적으로 알 수 있기 때문에 

효율적이고 정확한 프로그램을 작성할 수 있다.

 

ViewModel에서 LiveData를 사용하는데, 해당 데이터가 변경될 때 observe를 통한 관찰이 필요하다.

 

[개발일지]

 

두 가지 observe가 필요했다.

 

1. 현재 일정을 나타내는 task 인스턴스에서 값이 변하면 즉각적으로 recycler view 갱신

2. 현재 날짜를 나타내는 currentDayPosition에서 값이 변하면 즉각적으로 adapter 갱신 

 

live data를 살펴보면,

var taskLiveData = MutableLiveData<ArrayList<DayData>>()
var currentDayPosition= MutableLiveData<Int>()

 

위와 같으며 dayData 내부에 task 데이터가 저장되어 있다.

 

여러 가지 task를 변하게 만드는 기능을 사용할 때 observe를 통해서 즉각적인 갱신이 이루어져야 한다.

아래와 같은 함수들이 task live data를 변화하는 함수들이다.

 

fun delTaskData(task: Task){
    currentMonthArr[currentDayPosition.value!!].taskList?.remove(task)
    taskLiveData.value = currentMonthArr
}

fun doneTaskData(task : Task){
    task.isDone = true
    task.per = 100
    taskLiveData.value = currentMonthArr
}

fun setTaskICon(iconIndex:Int,task:Task){
    task.iconType = iconIndex
    taskLiveData.value = currentMonthArr
}

fun setPerTask(task:Task,p:Int){
    task.per = p
    taskLiveData.value = currentMonthArr
}

 

변화를 적용할 view가 있는 calss에서 observer를 선언한다.

 

mainActivity.viewModel.taskLiveData.observe(mainActivity, Observer {
    day.taskList?.let {
        (binding.taskView.adapter as TaskListAdapter).setData(it)
    }
})

 

live 데이터가 변화할 경우 observe로 관찰해서 뷰의 데이터를 갱신해준다.

setData 함수는 adapter 내부에서 선언한 함수로 recycler view를 갱신하는 코드를 작성했다.

 

fun setData(dataSet:ArrayList<Task>){
    itemList = dataSet
    notifyDataSetChanged()
}

 

주의할 점은  notifyDataSetChanged()는 시간 소모가 크므로 크지 않은 데이터에서만 사용한다.

큰 데이터를 관리하는 recycler view에서는 notifyItemChanged 등 하나의 데이터에 대한 변화만 갱신해야 한다.

 

나는 사용자의 일일 task 데이터가 그리 크지 않으므로 notifyDataSetChanged()을 사용했다.

 

다음으로는 현재 날짜가 변할 때의 observer 기능이 필요했다.

 

mainActivity.viewModel.currentDayPosition.observe(mainActivity, Observer { dayIndex->
    day = mainActivity.viewModel.currentMonthArr[dayIndex]
    initAdapter(day)
    binding.taskView.adapter  =taskListAdapter
})

 

viewModel의 currentDayPosition을 관찰하여 변경 시 adapter를 갱신한다.

각 day Position에 따른 task 데이터가 다르므로 adapter를  갱신하고 recycler View에 새로 부착한다.

 

두 가지 observer가 데이터 변화 시 즉각적으로 view를 갱신하는 기능을 할 것이다.

이제 애뮬레이터를 통해서 확인한다.

 

 

 

 

2가지 observer가 정확한 기능을 하고 있다.

task 데이터 변경 시 recycler view의 task도 바로 변경되며, 

다른 날짜로 변경 시에 새로운 adapter로 데이터를 그려주고 있었다.