Android 공부

LiveData의 간단한 예제

0. 해당 프로젝트는 이전 글인


2018/11/30 - [Android 공부] - android.arch.lifecycle


의 연장선입니다.

목표는 LiveData를 이용해서 값이 변경될 때마다, 자동으로 TextView 또한 변경하는 구조를 만들겠습니다.

   

-0.1

   LiveData는 기존의 프로젝트에서도 충분히 유용하게 사용될 것이라고 생각합니다.

   조금만 알게 되면 자동으로 값을 변경할 수 있는 코드를 작성할 수 있고, 데이터바인딩과 같이 사용할 경우 쉽게

   xml에서 코드를 변경할 것이기 때문입니다.


1. xml


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity.MainActivity">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/userIdTextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
    <EditText
        android:id="@+id/userInputET"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.169" />
 
    <Button
        android:id="@+id/loginBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/userInputET"
        app:layout_constraintVertical_bias="0.056" />
 
</android.support.constraint.ConstraintLayout>
cs


출력을 보여주는 TV, 입력하는 ET, 등록하는 Btn의 간단한 구조입니다.


2. 프로그래밍


1
2
3
4
5
6
7
8
9
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel
 
class UserInfos : ViewModel(){
    // Create a LiveData with a String
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }
}
cs


대부분의 LiveData는 ViewModel 이하에서 사용된다고 합니다.

currentName이라는 변수를 통해서 변할 수 있는 LiveData의 String형을 만들어준 것입니다.


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 
import android.arch.lifecycle.*
import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.widget.TextView
import hbs.com.studyandroidach.ViewModel.UserInfos
 
class MyObserver : LifecycleObserver{
 
    lateinit var userModel:UserInfos
    lateinit var context:Context
    //생성자를 통해서 lifecycle의 observer를 추가한다.
    constructor(context: Context, lifecycle:Lifecycle){
        lifecycle.addObserver(this)
        this.context = context
    }
 
    //OnLifecyclewEvent를 삭제해줬습니다.
    //ㅜㅜ...onCreate시에 파라매터를 전달해주고 싶었는데 찾아봐야 합니다.
    fun onCreate(lifecycleOwner: LifecycleOwner,printIDTV: TextView){
        Log.d("onStatus","onCreate");
        //userModel을 만들어줍니다.
        userModel = ViewModelProviders.of(context as AppCompatActivity).get(UserInfos::class.java)
        //userModel의 currentName의 옵저버를 만들어줍니다.
        //onChange 함수가 오버라이드 되어있으며,
        //currentName이 바뀔 때, 값을 it으로 리턴합니다.
        val userModelObs:Observer<String> = Observer {
            it ->
            Log.d("userId", it)
            printIDTV.text = it
        }
 
        //observe 해줍니다.
        userModel.currentName.observe(lifecycleOwner,userModelObs)
    }
 
    //onStart 이벤트
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onStart(){
        Log.d("onStatus", "onStart")
    }
 
    //onResume 이벤트
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume(){
        Log.d("onStatus","onResume");
    }
 
    //onPause 이벤트
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause(){
        Log.d("onStatus","onPause");
    }
 
    //onStop 이벤트
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop(){
        Log.d("onStatus","onStop");
    }
 
    //onDestroy 이벤트
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy(){
        Log.d("onStatus","onDestroy");
    }
 
}
cs


기존의 코드에서 onCreate 부분을 바꿔준 것입니다.

OnLifeCycle의 Event를 제거해줬습니다.

userModel = ViewModelProviders.of(context as AppCompatActivity).get(UserInfos::class.java)
을 통해서 userModel의 객체를 가져오고 observer를 만들고 텍스트가 변경될 때마다, setText를 해줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import hbs.com.studyandroidach.Observer.MyObserver
import hbs.com.studyandroidach.R
import kotlinx.android.synthetic.main.activity_main.*
 
class MainActivity : AppCompatActivity() {
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val myObserver = MyObserver(this, lifecycle)
        //ㅜㅜ...onCreate에 lifecycleOwner와 userIdTV를 넘겨줍니다.
        myObserver.onCreate(this, userIdTextView)
        //loginBtn을 클릭할 시에 userModel의 currentName의 값을 변경만 해줍니다.
        loginBtn.setOnClickListener {
            if(userInputET.text!=null){
                myObserver.userModel.currentName.value = userInputET.text.toString()
            }
        }
    }
}
cs


액티비티에서는 btn을 누르면

editText의 내용을 userModel.currentName.value에 set을 해주기만 합니다.


이렇게 하게 되면 lifecycleObserver에서 setText하고 있기 때문에 알아서 자동으로 setText가 됩니다.



'Android 공부' 카테고리의 다른 글

Android 2way databiding - bindingAdapter(2)  (0) 2018.12.12
안드로이드 2way DataBinding  (0) 2018.12.11
android.arch.lifecycle  (0) 2018.11.30
안드로이드 유튜브 플레이어 예제  (0) 2018.10.24
안드로이드 gitignore 예제  (0) 2018.10.24