-
[LifecycleOwner] LiveData를 Observe할수 있는 View가 필요할때개발/Android 2018. 5. 1. 20:33반응형
Android Architecture Components에서 Activity, Fragment는 LifecycleOwner가 구현이 되어있어서 별도의 커스텀 없이도 LiveData를 Observe해서 동작이 가능합니다. 하지만 하나의 Fragment혹은 Activity에서 너무 많은 동작을 하게 되어 각 기능별로 View를 분리하고싶을때! View는 LifecycleOwner가 없기 때문에 LiveData를 Observe하는 동작이 불가능합니다. 따라서 지난번에 구현한 MutableLiveDataExt를 참고하여 내부적으로 LifecycleOwner를 가지는 View클래스를 만들어 보겠습니다.
참고 : [LiveData] LiveData를 Background에서도 동작하게 해야 할때
기본 컨셉은 앞서 만들었던 MutableLiveDataExt와 마찬가지로 자체 LifecycleOwner를 생성하여 외부의 Lifecycle과 동기화 시켜 동작하도록 하는 것 입니다.
여기서는 FrameLayout을 상속받아 BaseView라는 클래스로 생성합니다.
public abstract class BaseView extends FrameLayout implements LifecycleOwner, LifecycleObserver { private LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this); public BaseView(@NonNull Context context) { super(context); init(); } public BaseView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public BaseView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { View view = createView(LayoutInflater.from(getContext()), this); setLayoutParams(view.getLayoutParams()); addView(view); ButterKnife.bind(this); onViewCreated(); } @Override public Lifecycle getLifecycle() { return lifecycleRegistry; } @OnLifecycleEvent(Lifecycle.Event.ON_ANY) void onStateEvent(LifecycleOwner owner, Lifecycle.Event event) { lifecycleRegistry.handleLifecycleEvent(event); } abstract protected View createView(LayoutInflater inflater, @Nullable ViewGroup container); abstract protected void onViewCreated(); }
LifecycleOwner 인터페이스를 구현하여 getLifecycle() 메소드를 통해 자체적으로 생성한 LifecycleRegistry 객체를 반환하도록 하였습니다. 또한 기본적으로 View는 Lifecycle이 동작하지 않기 때문에 동기화의 기준이 될 LifecycleOwner에 등록할 수 있도록 LifecycleObserver를 함께 구현하여 모든 Lifecycle 이벤트를 수신했을때 동기화 하도록 정의 했습니다.
마지막으로 클래스를 상속받아서 사용할때 사용자에게 View생성 및 초기화 시점을 강제해 주기위한 createView(), onViewCreated() 를 abstract로 정의하여 상속시 구현이 누락되는 경우가 없도록 하였습니다.
기본이 되는 클래스를 생성하였습니다. 위의 클래스를 이용하여 간단한 코드를 작성해 봅시다.
public class DrawMenu extends BaseView { @BindView(R.id.personpic) protected CircleImageView picture; @BindView(R.id.name) protected TextView personName; @BindView(R.id.company) protected TextView personCompany; public DrawMenu(Context context) { super(context); } public DrawMenu(Context context, AttributeSet attrs) { super(context, attrs); } public DrawMenu(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected View createView(LayoutInflater inflater, @Nullable ViewGroup container) { return inflater.inflate(R.layout.layout_left_drawer, container, false); } @Override protected void onViewCreated() { initData(); } private void initData() { CommonData.getInstance().personData.observe(this, new Observer
() { @Override public void onChanged(@Nullable PersonData personData) { if(personData == null) { return ; } personName.setText(personData.username); personCompany.setText(personData.company); Glide.with(picture).load(personData.profile).into(picture); } }); } ... } 사용자 정보를 Observe하는 DrawerLayout의 View를 생성했습니다.
public class MainActivity extends BaseActivity { @BindView(R.id.left_drawer) DrawMenu drawmenu; @BindView(R.id.drawer_layout) DrawerLayout drawerLayout; ... private void initView() { ... getLifecycle().addObserver(drawmenu); } ... }
마지막으로 Lifecycle을 맞추어야 하는 Activity, Fragment, View에서 addObserver로 등록해 줍니다.
실제 사용상에 View를 LifecycleOwner로 하여 별도의 모듈처럼 동작하게 하는 상황이 있을지 모르겠지만 Lifecycle을 이용하면서 독립적인 UI Componenet를 구성할때 사용가능할 듯 하여 만들어 보았습니다.
반응형'개발 > Android' 카테고리의 다른 글
[Retrofit / RxJava] 네트워크 요청 결과를 RxJava로 처리하자 -1- (0) 2019.03.13 [BroadcastReceiver] Broadcast permission 주기 (0) 2018.12.11 [LiveData] LiveData를 Background에서도 동작하게 해야 할때 (0) 2018.05.01 [RecyclerView.Adapter] RecyclerView에서 ChoiceMode처럼 쓰기 (0) 2018.04.09 [RecyclerView.Adapter] RecyclerView 편하게 쓰기 (0) 2018.04.08