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 |