package com.android.app_base.base.view;
|
|
|
import android.app.Activity;
|
import android.content.Context;
|
import android.content.Intent;
|
import android.os.Bundle;
|
import android.view.View;
|
import android.view.ViewGroup;
|
import android.view.Window;
|
import android.view.inputmethod.InputMethodManager;
|
|
import androidx.annotation.NonNull;
|
import androidx.annotation.Nullable;
|
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.ViewDataBinding;
|
import androidx.drawerlayout.widget.DrawerLayout;
|
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.ViewModelProvider;
|
|
import com.android.app_base.action.TitleBarAction;
|
import com.android.app_base.base.action.ClickAction;
|
import com.android.app_base.base.viewmodel.BaseViewModel;
|
import com.android.app_base.base.StateViewEnum;
|
import com.blankj.utilcode.util.ToastUtils;
|
import com.gyf.immersionbar.ImmersionBar;
|
import com.hjq.bar.TitleBar;
|
|
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.Type;
|
|
/**
|
* Activity基类,所有的 Activity 都要继承此类
|
*/
|
public abstract class BaseActivity<VDB extends ViewDataBinding,VM extends BaseViewModel> extends AppCompatActivity implements TitleBarAction, ClickAction {
|
protected VDB binding;
|
protected VM viewModel;
|
private int viewModelId;
|
/**
|
* 标题栏对象
|
*/
|
private TitleBar mTitleBar;
|
/**
|
* 状态栏沉浸
|
*/
|
private ImmersionBar mImmersionBar;
|
|
@Override
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
super.onCreate(savedInstanceState);
|
//Layout初始化
|
initLayout();
|
//页面参数初始化方法
|
initParam();
|
//页面view初始化方法
|
initView();
|
//页面事件监听的方法,用于ViewModel层转到View层的事件注册
|
initLiveDataObserve();
|
//页面数据初始化方法
|
initData();
|
}
|
|
|
@Override
|
protected void onDestroy() {
|
super.onDestroy();
|
//解除Messenger注册
|
// Messenger.getDefault().unregister(viewModel);
|
|
if(binding != null){
|
binding.unbind();
|
}
|
}
|
|
/**
|
* 初始化布局
|
*/
|
protected void initLayout(){
|
//绑定 ViewDataBinding 和 ViewModel
|
initViewDataBindingAndViewModel();
|
//初始化状态视图
|
initStateView();
|
//初始化沉浸式状态栏和 titleBar
|
initStatusBar();
|
initSoftKeyboard();
|
}
|
|
/**
|
* ViewDataBinding和 ViewModel的获取及相关绑定
|
*/
|
protected void initViewDataBindingAndViewModel() {
|
if (getLayoutId() > 0) {
|
binding = initViewBinding();
|
}
|
viewModelId = getVariableId();
|
viewModel = initViewModel();
|
if (binding != null){
|
//关联ViewModel
|
if (viewModelId > 0){
|
binding.setVariable(viewModelId, viewModel);
|
}
|
//支持LiveData绑定xml,数据改变,UI自动会更新
|
binding.setLifecycleOwner(this);
|
//让ViewModel拥有View的生命周期感应
|
getLifecycle().addObserver(viewModel);
|
}
|
}
|
|
/**
|
* 初始化ViewBinding
|
*/
|
protected VDB initViewBinding() {
|
return DataBindingUtil.setContentView(this, getLayoutId());
|
}
|
/**
|
* 初始化ViewModel
|
* @return 返回一个ViewModel
|
*/
|
protected VM initViewModel() {
|
Class<VM> vmClass;
|
Type type = getClass().getGenericSuperclass();
|
if (type instanceof ParameterizedType){
|
vmClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
|
} else {
|
//如果没有指定泛型参数,则默认使用BaseViewModel
|
vmClass = (Class<VM>) BaseViewModel.class;
|
}
|
return new ViewModelProvider(this, (ViewModelProvider.Factory) ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(vmClass);
|
}
|
|
|
/**
|
* 对状态视图liveData进行观察监听
|
*/
|
protected void initStateView() {
|
viewModel.getStateViewLiveData().observe(this, new Observer<StateViewEnum>() {
|
@Override
|
public void onChanged(StateViewEnum stateViewEnum) {
|
switch (stateViewEnum) {
|
case DIALOG_LOADING:
|
dialogLoading();
|
break;
|
case DIALOG_DISMISS:
|
dialogDismiss();
|
break;
|
case DATA_LOADING:
|
dataLoading();
|
break;
|
case DATA_FINISH:
|
dataFinish();
|
break;
|
case DATA_ERROR:
|
dataError();
|
break;
|
case DATA_NULL:
|
dataNull();
|
break;
|
case NET_ERROR:
|
netError();
|
break;
|
case HIDE:
|
hide();
|
break;
|
default:
|
break;
|
}
|
}
|
});
|
viewModel.getMessageLivaData().observe(this, new Observer<String>() {
|
@Override
|
public void onChanged(String message) {
|
ToastUtils.showShort(message);
|
}
|
});
|
}
|
|
|
|
/**
|
* 缺省页等状态视图的更新
|
* 有需求的,在子类选择重写
|
*/
|
protected void dialogLoading() {
|
}
|
protected void dialogDismiss() {
|
}
|
protected void dataLoading() {
|
}
|
protected void dataFinish() {
|
}
|
protected void dataError() {
|
}
|
protected void dataNull() {
|
}
|
protected void netError() {
|
}
|
protected void hide() {
|
}
|
|
/**
|
* 初始化沉浸式状态栏
|
*/
|
protected void initStatusBar(){
|
if (isStatusBarImmersionEnabled()) {
|
getImmersionBarConfig().init();
|
// 设置标题栏沉浸()
|
if (getTitleBar() != null) {
|
ImmersionBar.setTitleBar(this, getTitleBar());
|
getTitleBar().setOnTitleBarListener(this);
|
}
|
}
|
}
|
/**
|
* 是否使用沉浸式状态栏,可以子类重写指定
|
*/
|
protected boolean isStatusBarImmersionEnabled() {
|
return true;
|
}
|
/**
|
* 获取状态栏沉浸的配置对象
|
*/
|
@NonNull
|
public ImmersionBar getImmersionBarConfig() {
|
if (mImmersionBar == null) {
|
mImmersionBar = createStatusBarConfig();
|
}
|
return mImmersionBar;
|
}
|
/**
|
* 创建状态栏沉浸的配置对象
|
*/
|
@NonNull
|
protected ImmersionBar createStatusBarConfig() {
|
return ImmersionBar.with(this)
|
// 默认状态栏字体颜色为黑色
|
.statusBarDarkFont(isStatusBarDarkFont(),0.2f);//不写默认为亮色
|
}
|
/**
|
* 状态栏字体深色模式
|
*/
|
protected boolean isStatusBarDarkFont() {
|
return true;
|
}
|
@Override
|
@Nullable
|
public TitleBar getTitleBar() {
|
if (mTitleBar == null) {
|
mTitleBar = obtainTitleBar(findViewById(Window.ID_ANDROID_CONTENT));
|
}
|
return mTitleBar;
|
}
|
|
/**
|
* 获取根布局的id,由子类实现返回
|
* @return layout的id
|
*/
|
public abstract int getLayoutId();
|
|
/**
|
* 获取ViewModel的id,由子类实现返回
|
* @return BR中viewModel的id
|
*/
|
public abstract int getVariableId();
|
|
/**
|
* 初始化页面参数,例如从上一个activity传递过来的参数
|
*/
|
public abstract void initParam();
|
|
/**
|
* 初始化页面view,例如一些view的隐藏或显示,以及点击逻辑等用户交互
|
*/
|
public abstract void initView();
|
|
/**
|
* 初始化页面数据
|
*/
|
public abstract void initData();
|
|
/**
|
* 初始化LiveData的监听
|
* 简单的数据展示可通过DataBinding直接双向绑定到xml中
|
*/
|
public abstract void initLiveDataObserve();
|
|
@Override
|
public void finish() {
|
hideSoftKeyboard();
|
super.finish();
|
}
|
|
/**
|
* 隐藏软键盘
|
*/
|
protected void hideSoftKeyboard() {
|
// 隐藏软键盘,避免软键盘引发的内存泄露
|
View view = getCurrentFocus();
|
if (view != null) {
|
InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
if (manager != null && manager.isActive(view)) {
|
manager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
|
view.clearFocus();
|
}
|
}
|
}
|
|
/**
|
* 初始化软键盘
|
*/
|
protected void initSoftKeyboard() {
|
// 点击外部隐藏软键盘,提升用户体验
|
getContentView().setOnClickListener(v -> hideSoftKeyboard());
|
}
|
|
public ViewGroup getContentView() {
|
return findViewById(Window.ID_ANDROID_CONTENT);
|
}
|
|
public Activity getSelfActivity() {
|
return this;
|
}
|
|
/**
|
* 如果当前的 Activity(singleTop 启动模式) 被复用时会回调
|
*/
|
@Override
|
protected void onNewIntent(Intent intent) {
|
super.onNewIntent(intent);
|
// 设置为当前的 Intent,避免 Activity 被杀死后重启 Intent 还是最原先的那个
|
setIntent(intent);
|
}
|
|
}
|