应用场景:小项目快速开发、无快速重复加载业务需求、不考虑性能问题。
封装思想:通过泛型直接指定ViewBinding、ViewModel的类型,外部暴露initView()、initData()、initViewModelOwner()。
/**
* @author : ZGS
* Created on 2022/5/12
**/
public abstract class BaseFragment<V extends ViewBinding, VM extends ViewModel> extends RxFragment {
private static final String TAG = "BaseFragment";
public V binding;
public VM viewModel;
private ViewModelStoreOwner owner;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// 初始化viewBinding、viewModel
init(inflater, container, false);
initView();
initData();
return binding.getRoot();
}
/**
* 初始化视图
*/
protected abstract void initView();
/**
* 初始化数据
*/
protected abstract void initData();
/**
* 绑定ViewModel持有者
*
* @return true:Activity持有;false:fragment自身持有
*/
protected abstract boolean initViewModelOwner();
/**
* 初始化viewBinding和viewModel
*
* @param inflater
* @param parent 父容器
* @param attachToRoot
*/
private void init(LayoutInflater inflater, ViewGroup parent, boolean attachToRoot) {
owner = initViewModelOwner() ? requireActivity() : this;
Type type = this.getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
// 获取真实泛型
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
Class<V> viewBindingClass = (Class<V>) types[0];
Class<VM> viewModelClass = (Class<VM>) types[1];
try {
// 绑定viewBinding
Method method = viewBindingClass.getMethod("inflate", LayoutInflater.class,
ViewGroup.class, boolean.class);
binding = (V) method.invoke(null, inflater, parent, attachToRoot);
// 绑定viewModel
viewModel = new ViewModelProvider(owner).get(viewModelClass);
} catch (NoSuchMethodException e) {
Log.e(TAG,"找不到inflater方法:" + e);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.e(TAG,"反射失败:" + e);
}
}
}
}