一、前言
本文提供了一个基类,通过继承基类和传入泛型类型就可以实现创建ViewModel和绑定ViewDataBinding的工作。
二、基本使用
继承BaseInflateActivity即可
public abstract class BaseInflateActivity<VM extends AndroidViewModel, VDB extends ViewDataBinding> extends AppCompatActivity {
protected VDB mBinding;
protected VM mViewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = ViewDataBindingHelper.inflateVDB(this,this.getClass());
setContentView(mBinding.getRoot());
mBinding.setLifecycleOwner(this);
mViewModel= ViewModelHelper.createAndroidViewModel(this,this.getClass());
}
public VDB getBinding() {
return mBinding;
}
public VM getViewModel() {
return mViewModel;
}
}
其他类
ViewDataBindingHelper
public class ViewDataBindingHelper {
/**
* 生成ViewDataBinding
*
* @param context
* @param <VDB>
* @return
*/
public static <VDB extends ViewDataBinding> VDB inflateVDB(Context context, Class clazz) {
Class modelClass = getViewDataBindingModelClass(clazz);
if (modelClass != null) {
Method inflate = null;
try {
inflate = modelClass.getDeclaredMethod("inflate", LayoutInflater.class);
return (VDB) inflate.invoke(null, LayoutInflater.from(context));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 生成ViewDataBinding
*
* @param context
* @param <VDB>
* @return
*/
public static <VDB extends ViewDataBinding> VDB inflateVDB(Context context, ViewGroup parent, Class clazz) {
Class modelClass = getViewDataBindingModelClass(clazz);
if (modelClass != null) {
Method inflate = null;
try {
inflate = modelClass.getDeclaredMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);
return (VDB) inflate.invoke(null, LayoutInflater.from(context),parent,false);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 获取ViewDataBinding的具体类
*
* @param clazz
* @return
*/
private static Class getViewDataBindingModelClass(Class clazz) {
Class modelClass = null;
Type type = clazz.getGenericSuperclass();
if (type == null)
return null;
if (type instanceof ParameterizedType) {
ParameterizedType tmpType = (ParameterizedType) type;
for (Type t : tmpType.getActualTypeArguments()) {
if (t instanceof Class && instanceOfViewDataBinding((Class) t))
modelClass = (Class) t;
}
if (modelClass == null)
modelClass = getViewDataBindingModelClass(clazz.getSuperclass());
} else {
modelClass = getViewDataBindingModelClass(clazz.getSuperclass());
}
return modelClass;
}
/**
* 判断一个类是否继承ViewDataBinding
*
* @param clazz
* @return
*/
private static boolean instanceOfViewDataBinding(Class clazz) {
if (clazz == null)
return false;
if (!ViewDataBinding.class.isAssignableFrom(clazz))
return instanceOfViewDataBinding(clazz.getSuperclass());
else
return true;
}
}
ViewModelHelper
public class ViewModelHelper {
/**
* 生成ViewModel
* @param owner
* @param <VM>
* @return
*/
public static <VM extends ViewModel> VM createAndroidViewModel(ViewModelStoreOwner owner,Class clazz) {
Class modelClass = getViewModelClass(clazz);
return (VM) new ViewModelProvider(owner).get(modelClass);
}
/**
* 获取ViewModel具体类
* @param clazz
* @return
*/
private static Class getViewModelClass(Class clazz) {
Class modelClass = null;
Type type = clazz.getGenericSuperclass();
if (type == null)
return null;
if (type instanceof ParameterizedType) {
ParameterizedType tmpType = (ParameterizedType) type;
for (Type t : tmpType.getActualTypeArguments()) {
if (t instanceof Class&&instanceOfViewModel((Class) t))
modelClass = (Class) t;
}
if (modelClass == null)
modelClass = getViewModelClass(clazz.getSuperclass());
} else {
modelClass = getViewModelClass(clazz.getSuperclass());
}
return modelClass;
}
/**
* 判断是否继承于ViewMdoel
* @param clazz
* @return
*/
private static boolean instanceOfViewModel(Class clazz) {
if (clazz == null)
return false;
if (!ViewModel.class.isAssignableFrom(clazz))
return instanceOfViewModel(clazz.getSuperclass());
else
return true;
}
}