말씀하신 대로 LiveData는 Observer 기법을 사용합니다. 님의 코드에서 test()메소드가ViewModel에 있는 currentName을 observe 하는 코드입니다.
private void test() {
Observer<String> nameObserver = newName -> nameTextView.setText(newName);
nameViewModel.getCurrentName().observe(this, nameObserver);
Log.e("T", "2");
}
코드를 보시면 observe(this, nameObserver)라고 되어 있습니다. observe의 원형을 문서에서 확인해 보시면 아시겠지만, getCurrentName()에 어떤 변경사항이 생길 때마다 nameObserver 에 있는 onChanged 메소드를 호출하도록 되어 있습니다.
https://developer.android.com/reference/androidx/lifecycle/LiveData
https://developer.android.com/reference/androidx/lifecycle/Observer
abstract void onChanged(T t)
참고로
Observer<String> nameObserver = newName -> nameTextView.setText(newName);
위의 코드는 lambda expression으로 아래와 같이 길게 되어 있던 코드를 위처럼 간단하게 바꾼 겁니다.
Observer<String> nameObserver = new Observer<>() {
@Override
public void onChanged(String newName) {
nameTextView.setText(newName);
}
}
람다식은 인터페이스의 메소드가 한개만 존재할 때, 인터페이스의 인스턴스 생성 부분과 메소드의 이름부를 생략하고 메소드 부분만 적을 수 있도록 해줌
nameObserver를 인라인으로 만들어 보면 아래와 같습니다.
nameViewModel.getCurrentName().observe(this,new Observer<>() {
@Override public void onChanged (String newName){
nameTextView.setText(newName);
}
} );
따라서 위의 코드는 "nameViewModel의 currentName이 변경이 있을 때마다 onChange메소드에 있는 코드, 즉, nameTextView에 새로운 이름을 표시하겠다"로 읽을 수 있습니다.
그리고 nameViewModel의 currentName의 변경은 아래의 코드가 시작하고 있습니다.
inputButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String inputName = nameInputView.getText().toString();
nameViewModel.getCurrentName().setValue(inputName);
}
});
따라서 버튼을 누를 때마 NameViewModel에 있는 LiveData인 currentName이 변경이 되므로, 이걸 observe하고 있는 nameObserver.onChange 메소드가 실행되게 되는 것입니다.
이해가 가시나요?
참고로, 한가지 신경쓰셨으면 하는 부분이 있어서 말씀드립니다.
public class NameViewModel extends ViewModel {
...
public LiveData<String> getCurrentName(){ ... }
}
ViewModel에서 LiveData를 외부에 공개할 때는 멤버필드에 바로 접근할 수 없도록 해주어야 합니다. MutableLiveData를 public으로 만들경우, 아래처럼,
nameViewModel.getCurrentName().setValue(inputName);
뷰에서 LiveData를 직접 수정하게 됩니다. 이건 OOP의 기본원칙인 encapsulation을 깨뜨리게 되므로 LiveData타입으로 읽기전용을 만들어 주시고 LiveData의 변경은 별도의 메소드를 공개하여 처리하는 것을 권장합니다.
public class NameViewModel extends ViewModel { ...
private MutableLiveData<String> currentName = new MutableLiveData<>();
public LiveData<String> getCurrentName() {
return currentName;
}
public void onNameChanged(String name) {
currenName.postValue(name);
}
}
도움이 되시길.