| | |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.view.Window; |
| | | |
| | | import androidx.annotation.IdRes; |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | import androidx.databinding.DataBindingUtil; |
| | | import androidx.databinding.ViewDataBinding; |
| | | import androidx.fragment.app.Fragment; |
| | | import androidx.fragment.app.FragmentActivity; |
| | | import androidx.lifecycle.Observer; |
| | | import androidx.lifecycle.ViewModelProvider; |
| | | |
| | | import com.android.app_base.action.TitleBarAction; |
| | | import com.android.app_base.base.StateViewEnum; |
| | | import com.android.app_base.base.viewmodel.BaseViewModel; |
| | | import com.gyf.immersionbar.ImmersionBar; |
| | | import com.hjq.bar.TitleBar; |
| | | |
| | | import java.lang.reflect.ParameterizedType; |
| | | import java.lang.reflect.Type; |
| | |
| | | * @date 2023.03.02. 15:50 |
| | | * @desc Fragment基类 |
| | | */ |
| | | public abstract class BaseFragment<V extends ViewDataBinding,VM extends BaseViewModel> extends Fragment { |
| | | public abstract class BaseFragment<V extends ViewDataBinding,VM extends BaseViewModel> extends Fragment implements TitleBarAction { |
| | | protected V binding; |
| | | protected VM viewModel; |
| | | private int viewModelId; |
| | | |
| | | /** |
| | | * 标题栏对象 |
| | | */ |
| | | private TitleBar mTitleBar; |
| | | /** |
| | | * 状态栏沉浸 |
| | | */ |
| | | private ImmersionBar mImmersionBar; |
| | | /** |
| | | * 根布局 |
| | | */ |
| | | private View mRootView; |
| | | /** |
| | | * 该Fragment是否加载过数据 |
| | | * */ |
| | | private boolean isLoaded; |
| | | |
| | | |
| | | @Override |
| | |
| | | @Nullable |
| | | @Override |
| | | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { |
| | | binding = DataBindingUtil.inflate(inflater,getLayoutId(), container, false); |
| | | return binding.getRoot(); |
| | | isLoaded = false; |
| | | if (getLayoutId() > 0){ |
| | | binding = DataBindingUtil.inflate(inflater,getLayoutId(), container, false); |
| | | mRootView = binding.getRoot(); |
| | | return mRootView; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | |
| | | initStateView(); |
| | | //页面view初始化方法 |
| | | initView(); |
| | | //页面数据初始化方法 |
| | | initData(); |
| | | //页面事件监听的方法,用于ViewModel层转到View层的事件注册 |
| | | initLiveDataObserve(); |
| | | } |
| | | |
| | | @Override |
| | | public void onResume() { |
| | | super.onResume(); |
| | | //初始化沉浸式状态栏和 titleBar |
| | | initStatusBar(); |
| | | if (!isLoaded){ |
| | | //页面数据初始化方法 |
| | | initData(); |
| | | isLoaded = true; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void onDestroyView() { |
| | | super.onDestroyView(); |
| | | //解除Messenger注册 |
| | | // Messenger.getDefault().unregister(viewModel); |
| | | |
| | | if(binding != null){ |
| | | binding.unbind(); |
| | | } |
| | | mRootView = null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * ViewDataBinding和 ViewModel的获取及相关绑定 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 初始化沉浸式状态栏 |
| | | */ |
| | | protected void initStatusBar(){ |
| | | if (isStatusBarImmersionEnabled()) { |
| | | getImmersionBarConfig().init(); |
| | | // 设置标题栏沉浸() |
| | | if (getTitleBar() != null) { |
| | | ImmersionBar.setTitleBar(this, getTitleBar()); |
| | | getTitleBar().setOnTitleBarListener(this); |
| | | } |
| | | } |
| | | } |
| | | /** |
| | | * 是否使用沉浸式状态栏,可以子类重写指定 |
| | | */ |
| | | protected boolean isStatusBarImmersionEnabled() { |
| | | return false; |
| | | } |
| | | /** |
| | | * 获取状态栏沉浸的配置对象 |
| | | */ |
| | | @NonNull |
| | | public ImmersionBar getImmersionBarConfig() { |
| | | if (mImmersionBar == null) { |
| | | mImmersionBar = createStatusBarConfig(); |
| | | } |
| | | return mImmersionBar; |
| | | } |
| | | /** |
| | | * 创建状态栏沉浸的配置对象 |
| | | */ |
| | | @NonNull |
| | | protected ImmersionBar createStatusBarConfig() { |
| | | return ImmersionBar.with(this) |
| | | // 默认状态栏字体颜色为黑色 |
| | | .statusBarDarkFont(isStatusBarDarkFont(),0.2f)//不写默认为亮色 |
| | | .keyboardEnable(false);// 解决软键盘与底部输入框冲突问题,默认为false,还有一个重载方法,可以指定软键盘mode |
| | | } |
| | | /** |
| | | * 获取状态栏字体颜色 |
| | | */ |
| | | protected boolean isStatusBarDarkFont() { |
| | | // 返回真表示黑色字体 |
| | | return true; |
| | | } |
| | | @Override |
| | | @Nullable |
| | | public TitleBar getTitleBar() { |
| | | if (mTitleBar == null) { |
| | | mTitleBar = obtainTitleBar((ViewGroup) getView()); |
| | | } |
| | | return mTitleBar; |
| | | } |
| | | /** |
| | | * 获取根布局的id,由子类实现返回 |
| | | * @return layout的id |
| | | */ |
| | | public abstract int getLayoutId(); |
| | | protected abstract int getLayoutId(); |
| | | |
| | | /** |
| | | * 获取ViewModel的id,由子类实现返回 |
| | | * @return BR中viewModel的id |
| | | */ |
| | | public abstract int getVariableId(); |
| | | protected abstract int getVariableId(); |
| | | |
| | | /** |
| | | * 初始化页面参数,例如从上一个activity传递过来的参数 |
| | | */ |
| | | abstract void initParam(); |
| | | protected abstract void initParam(); |
| | | |
| | | /** |
| | | * 初始化页面view,例如一些view的隐藏或显示,以及点击逻辑等用户交互 |
| | | */ |
| | | abstract void initView(); |
| | | protected abstract void initView(); |
| | | |
| | | /** |
| | | * 初始化页面数据 |
| | | */ |
| | | abstract void initData(); |
| | | protected abstract void initData(); |
| | | |
| | | /** |
| | | * 初始化LiveData的监听 |
| | | * 简单的数据展示可通过DataBinding直接双向绑定到xml中 |
| | | */ |
| | | abstract void initLiveDataObserve(); |
| | | protected abstract void initLiveDataObserve(); |
| | | |
| | | |
| | | public FragmentActivity getSelfActivity() { |
| | | return getActivity(); |
| | | } |
| | | @NonNull |
| | | @Override |
| | | public View getView() { |
| | | return mRootView; |
| | | } |
| | | |
| | | /** |
| | | * 根据资源 id 获取一个 View 对象 |
| | | */ |
| | | public <V extends View> V findViewById(@IdRes int id) { |
| | | return mRootView.findViewById(id); |
| | | } |
| | | |
| | | |
| | | } |