Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
관리 메뉴

Dev.

Android[Kotlin] 에서 LiveData 를 사용하는 간단한 예제 본문

Android

Android[Kotlin] 에서 LiveData 를 사용하는 간단한 예제

Pppdw 2019. 11. 13. 11:38

0. 개념

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

꼭 정독 하기를..

포스팅 목적 자체가 간단한 구현이기에 따로 개념 설명까지는 생략 하겠다.

애초에 잘못 설명 할 까 걱정되니까..

(그냥 한 번 이런 느낌이구나, 맛만 볼 수 있는 수준의 포스팅이다. )

1. 개요

MVVM + AAC 체제를 정말 간단히 맛만 볼 수 있는 수준으로 기재할 목적으로 포스팅 하게 되었다.

이 글 에서는 Room 및 xml data 같은 개념은 구현하지 않고, 딱 1개의 data 를 예로

  • LiveData 가 어떻게 구현 되는지 ?

  • 그래서 뷰에 어떻게 적용이 되는지 ?

만 체크 할 목적이다. 말 그대로 정말 기본적인 뼈대 구현의 포스팅.

 

2. LIVE DATA

( 참고 : https://developer.android.com/topic/libraries/architecture/livedata )

MVVM 에서 사용했던 Obserable 과 비슷한 맥락이다.

Data 가 변경 되었을 때 Observable callback 에서 이를 내려받고 그에 따른 View 의 상태를 변경할 수 있다.

LiveData 는 Lifecycle 을 알기에, 필요하지 않은 경우 callback 에 값을 주지 않는다. (예 : stop, pause... 등)

 

3. 구성도

Android AAC (!!이 포스팅에서는 Room 까지 구현하지 않는다.)

 

4. 구현

0) app.gradle

apply plugin: 'kotlin-android-extensions'

implementation 'android.arch.lifecycle:extensions:1.1.1'
kapt 'android.arch.lifecycle:compiler:1.1.1'

- 코틀린의 기본 libs 는 추가를 해놓았다고 가정한다.

 

1 ) Activity

class QuizDetailActivity : AppCompatActivity() {

    lateinit var model: QuizDetailViewModel

    private val observeListener = Observer<Quiz> {
        it?.let { quiz ->
			//todo..
            //ex textview.text = quiz.name
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_quiz_detail)

        model = ViewModelProviders.of(this).get(QuizDetailViewModel::class.java)
        if(::model.isInitialized){
            model.quiz.observe(this, observeListener)
        }

        model.request(2)
    }

}

- 위 글에서 설명 했던 callback 은 코드 상단의 ovserveListener 을 지칭한다.

- onCreate 에서 viewmodel 에 대한 init 검증을 한 후 observe 를 등록한다. ( lateinit 이란? -- Kotlin - 늦은 초기화 (1) lateinit )

- 정상적으로 동작한다면, quiz 모델의 변경이 감지 되었을 때 callback 에서 it 을 받아 볼 수 있고 그 것으로 뷰를 조작할 수 있다.

 

2 ) ViewModel

class QuizDetailViewModel: ViewModel(){

    private val repo = QuizDetailRepository()
    private val _quiz = MutableLiveData<Quiz>()
    
    val quiz: LiveData<Quiz> = _quiz

    fun request(index: Int) {
    	repo.getQuiz(index).let { it ->
            _quiz.value = it
        }
    }

}

- Activity 에서 viewmodel 의 request 를 호출 하였을 때 repository 에서 변경된 모델을 얻어 MutableLiveData에 채워 넣고, LiveData를 갱신한다.

 

3) Repository

class QuizDetailRepository {

    private var quiz = QuizMethod().searchQuiz(0)

    fun getQuiz(_index: Int): Quiz? {
        val _quiz = QuizMethod().searchQuiz(_index)
        _quiz?.let {
            quiz = _quiz
        }
        return quiz
    }

}

- getQuiz (==getModel) 을 요청 받았을 때 요청 받은 정보에 맞는 모델을 리턴 해 줘야한다. 여기서는 따로 API 등이 없기에 바로 하드코딩된 모델을 넘겨주지만, 실제론 이 부분에서 API 요청 등 을 작성하여도 무방하다.

- getQuiz (==getModel) 을 호출하는 주체는 viewmodel 이어야 한다.

 

4) Model

data class Quiz(val number: Int, val name: String, val desc:String, val answerType: Int) : ViewModel() {

    object AnswerType{
        const val INTEGER = 1
    }

    object Number{
        const val Q1 = 1
        const val Q1 = 2
    }

    var answer = ""
    var result = ""
    var maxValue = 0
}

class QuizMethod {

    val quizArray: HashMap<Int, Quiz>
        get() {
            val hash = hashMapOf(
                    Quiz.Number.Q1 to quiz1,
                    Quiz.Number.Q2 to quiz2
            )
            return hash
        }


    private val quiz1: Quiz
        get() {
            val number = Quiz.Number.Q1
            val name = "name1"
            val desc = "desc1"

            val quiz_ = Quiz(number, name, desc, Quiz.AnswerType.INTEGER)

            return quiz_
        }

    private val quiz2: Quiz
        get() {
            val number = Quiz.Number.Q2
            val name = "name2"
            val desc = "desc2"

            val quiz_ = Quiz(number, name, desc, Quiz.AnswerType.INTEGER)

            return quiz_
        }

    fun searchQuiz(index: Int): Quiz?{
        return quizArray[index]
    }
}

 

5. 마치며

라이브 데이터를 단 한번도 구현 해보지 않은 상태라면 코드를 복붙으로라도 한번 구현 해 보고 developers 의 livedata 를 참조하면 조금이라도 더 이해가 잘 되지 않을까?

개념 설명 하나 없는 영양가 없는 글이 되었지만 적어도 나 같은 누군가 에게는 도움이 되었으면 좋겠다.

 

 

 

 

Comments