BaseLayout

39 阅读1分钟
package com.alibaba.genie.panel.basic.base;

import android.app.Application;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModel;
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelStoreOwner;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;

import com.alibaba.genie.panel.basic.R;
import com.alibaba.genie.panel.basic.base.mvvm.BaseViewModel;
import com.alibaba.genie.panel.basic.base.mvvm.IBaseView;
import com.alibaba.genie.panel.basic.component.bus.LiveBus;
import com.alibaba.genie.panel.basic.widget.IotToast;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class BaseLayout<T extends ViewDataBinding, VM extends BaseViewModel> extends ConstraintLayout
        implements IBaseView, View.OnClickListener {

    //    protected AppPref_ preference = AppPref_.getInstance();
    protected LiveBus liveBus = LiveBus.getInstance();

    protected FrameLayout root;
    protected FrameLayout container;
    protected Context context;

    @NonNull
    protected T binding;
    public VM viewModel;

    public BaseLayout(@NonNull Context context) {
        this(context, null);
    }

    public BaseLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BaseLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = getContext();
        initTypeArray(context, attrs, defStyleAttr);
        binding = DataBindingUtil.inflate(LayoutInflater.from(context), initContentView(), this, true);
        root = findViewById(R.id.layout_root);
//        if (context instanceof BaseViewActivity) {
        Class vmClass = getViewModelClass();
        viewModel = (VM) createViewModel(null, vmClass);
        binding.setVariable(initVariableId(), viewModel);
//        } else {
//            throw new IllegalArgumentException("Context must be BaseViewActivity.");
//        }
        initData();
        initView();
        initViewObservable();
        //私有的ViewModel与View的契约事件回调逻辑
        registerUiChangeLiveDataCallBack();
    }

    protected void initTypeArray(Context context, AttributeSet attrs, int defStyleAttr) {

    }

    /**
     * 获取ViewModel的泛型
     *
     * @return
     */
    private Class getViewModelClass() {
        Type type = getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
            return (Class) actualTypeArguments[actualTypeArguments.length-1];
        } else {
            //默认使用BaseViewModel
            return BaseViewModel.class;
        }
    }

    @NonNull
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
        return ViewModelProvider.AndroidViewModelFactory.getInstance((Application) getContext().getApplicationContext());
    }

    /**
     * 创建ViewModel
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T extends ViewModel> T createViewModel(ViewModelStoreOwner owner, Class<T> cls) {
        return getDefaultViewModelProviderFactory().create(cls);
    }

    /**
     * 初始化布局
     *
     * @return int
     */
    public abstract int initContentView();

    @Override
    public boolean initData() {
        return true;
    }

    @Override
    public void initViewObservable() {

    }

    @Override
    public void onClick(View v) {

    }

    /**
     * 获取 LifecycleOwner
     */
    public LifecycleOwner getLifecycleOwner() {
        if (getContext() instanceof LifecycleOwner) {
            return (LifecycleOwner) getContext();
        }
        throw new UnsupportedOperationException(
                "如果想要在自定义布局中使用 LiveBus ,Context 必须是一个 LifecycleOwner" + "\n"
                        + "If you want to use the LiveBus, the Context must be a LifecycleOwner");
    }


    /**
     * 开启加载对话框
     */
    protected void showLoading() {
        BaseViewActivity activity = getActivity();
        if (activity != null) {
            activity.showLoading();
        }
    }

    /**
     * 开启加载对话框
     *
     * @param info
     */
    public void showLoading(String info) {
        BaseViewActivity activity = getActivity();
        if (activity != null) {
            activity.showLoading(info);
        }
    }

    /**
     * 关闭加载对话框
     */
    protected void hideLoading() {
        BaseViewActivity activity = getActivity();
        if (activity != null) {
            activity.hideLoading();
        }
    }

    protected void showToast(String msg){
        IotToast.makeIconText(context, msg).show();
    }

    protected BaseViewActivity getActivity() {
        if (context instanceof BaseViewActivity) {
            return (BaseViewActivity) context;
        }
        return null;
    }

    /**
     * 注册ViewModel与View的契约UI回调事件
     */
    protected void registerUiChangeLiveDataCallBack() {
        //Toast
        viewModel.getUiChange().showToastEvent.observe(getActivity(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                showToast(s);
            }
        });
        //显示Loading
        viewModel.getUiChange().showLoadingEvent.observe(getActivity(), new Observer<String>() {
            @Override
            public void onChanged(String info) {
                if (TextUtils.isEmpty(info)) {
                    showLoading();
                } else {
                    showLoading(info);
                }
            }
        });
        //隐藏Loading
        viewModel.getUiChange().hideStateViewEvent.observe(getActivity(), new Observer<Void>() {
            @Override
            public void onChanged(Void aVoid) {
                hideLoading();
            }
        });
    }
}