ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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를 구성할때 사용가능할 듯 하여 만들어 보았습니다.

    반응형
Designed by Tistory.