本文主要是介绍ViewBinding与MVVM框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
MVVM框架主要的特点就是低耦合,对于不同的view,model可以复用。
目前android 的MVVM框架主要是使用 databinding实现双向数据绑定,来降低耦合度。
首先是用databinding来实现mvvm框架,下面是一个我自己总结的使用databinding来实现mvvm框架的简单示例。
之后是我使用Viewbinding实现的框架,可以说用起来更加的灵活便捷。
model类,这个类主要是一些与视图相关的业务逻辑的处理,对于一些需要复用并且实现不同逻辑的model类,可以使用回调的方式来执行不同的业务逻辑。例如下面代码中的titlemodel, 需要更新数据的时候,需要调用notifyPropertyChanged(BR.title)来刷新页面数据
public abstract class BaseModel<T> extends BaseObservable {protected ProgressDialog mProgressDialog;protected T binding;protected Activity context;public BaseModel(T binding, Activity context){this.binding=binding;this.context=context;}public BaseModel(T binding){this.binding=binding;}}
public class TitleModel extends BaseModel<LayoutTextTitleBinding> {private String title;private OnClick onClick;private int actionIcon;public void setOnClick(OnClick onClick) {this.onClick = onClick;}public TitleModel(LayoutTextTitleBinding binding) {super(binding);}@Bindablepublic int getActionIcon() {return actionIcon;}public void setActionIcon(int actionIcon) {this.actionIcon = actionIcon;
// notifyPropertyChanged(BR.titleModel);}public void onBack(View view) {onClick.onBack(view);}public void onAction(View view) {onClick.onAction(view);}@Bindablepublic String getTitle() {return title;}public void setTitle(String title) {this.title = title;
// notifyPropertyChanged(BR.titleModel);}public static interface OnClick{void onBack(View view);void onAction(View view);}
}
public class TestActivityModel extends BaseModel<LayoutTestActivityBinding> {private TestAdapter testAdapter;public TitleModel titleModel;public TestActivityModel(LayoutTestActivityBinding binding) {super(binding);}public TestActivityModel(LayoutTestActivityBinding binding, final Activity activity) {super(binding, activity);titleModel=new TitleModel(binding.title);titleModel.setActionIcon(R.mipmap.ic_launcher);titleModel.setOnClick(new TitleModel.OnClick() {@Overridepublic void onBack(View view) {Toast.makeText(activity,"按下返回键",Toast.LENGTH_SHORT).show();}@Overridepublic void onAction(View view) {Toast.makeText(activity,"按下动作键",Toast.LENGTH_SHORT).show();}});binding.title.setTitleModel(titleModel);LinearLayoutManager layoutManager =new LinearLayoutManager(activity,LinearLayoutManager.VERTICAL,false);testAdapter = new TestAdapter(activity);testAdapter.setOnClick(new TestAdapter.OnClick() {@Overridepublic void onClick(View view, TestEntity info, int position) {}@Overridepublic void onLongClick(View view, TestEntity info, int pos) {}});binding.list.setLayoutManager(layoutManager);binding.list.setAdapter(testAdapter);getData();}int count;private void getData(){ArrayList<TestEntity> data=new ArrayList<>();for(int i=count;i<count+10;i++){TestEntity entity=new TestEntity();entity.setContent("context"+i);entity.setName("item"+i);data.add(entity);}count+=10;testAdapter.setmDatas(data);testAdapter.notifyDataSetChanged();}public void onRefresh(View view){getData();}}
关于Viewbinding。viewbinding会比databinding更加简单。并且不需要在xml文件中进行修改。下面是一个关于viewbinding的示例。同样是mvvm框架,使用viewbinding改进以后可以更加灵活的使用。比如两个完全不同的布局,也可以使用同一个model。不仅仅是相同视图情况下代码重用。下面是两种model的写法,一种指定了viewbinding的具体类型,一种没有。对于需要复用的model类,如果布局不复用也可以不指定具体的model类型,可以通过代码回调或者类型判断来执行不同的业务逻辑处理。需要复用的model不和activity关联,所以提供下面SimpleBaseModel的形式。
public abstract class BaseModel<T extends ViewBinding> implements View.OnClickListener {protected T binding;protected Activity context;public BaseModel(T binding,Activity context){this.binding=binding;this.context=context;}public BaseModel(T binding){this.binding=binding;}public abstract void onResume();public abstract void onActivityResult(int requestCode, int resultCode, Intent data);public abstract void onPause();public abstract void onDestroy();public abstract void onRestart();public abstract void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults);protected void bindListener(View... views){for (View view:views) {view.setOnClickListener(this);}}}
public abstract class SimpleBaseModel <T extends ViewBinding> implements View.OnClickListener {protected T binding;protected Activity context;public SimpleBaseModel(T binding, Activity context){this.binding=binding;this.context=context;}public SimpleBaseModel(T binding){this.binding=binding;}protected void bindListener(View... views){for (View view:views) {view.setOnClickListener(this);}}
}
public abstract class BaseActivity<T extends ViewBinding,M extends BaseModel> extends AppCompatActivity{protected T binding;protected M model;@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);onPrepare();binding=getBinding();setContentView(binding.getRoot());model=getModel();}@Overrideprotected void onDestroy() {super.onDestroy();model.onDestroy();}@Overrideprotected void onPause() {super.onPause();model.onPause();}@Overrideprotected void onResume() {super.onResume();model.onResume();}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);model.onActivityResult(requestCode, resultCode, data);}@Overrideprotected void onRestart() {super.onRestart();model.onRestart();}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);model.onRequestPermissionsResult(requestCode, permissions, grantResults);}protected abstract void onPrepare();protected abstract T getBinding();protected abstract M getModel();
}
下面是使用的例子,viewbinding可以灵活的引用include导入的布局,这里只是做一个范例,如果只是修改标题这种简单的逻辑,可以直接使用第三种写法。 其他两种model的形式,可以用于业务逻辑比较多的代码逻辑。对于model1的写法,是有重复布局的情况。model2的写法,是应用于业务逻辑大量重复,但布局不同的情况。可以在代码判断传入的binding的类型,对不同的视图进行不同的处理,也可以增加公共的回调接口进行处理
public class MainModel extends BaseModel<ActivityMainBinding> {TitleModel titleModel;TitleModel2 titleModel2;public MainModel(ActivityMainBinding binding, Activity context) {super(binding, context);titleModel=new TitleModel(binding.title,context);titleModel.setTitle("标题");titleModel2=new TitleModel2(binding.title,context);titleModel2.setTitle();binding.title.tx.setText("标题");//第三种写法}public MainModel(ActivityMainBinding binding) {super(binding);}@Overridepublic void onResume() {}@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {}@Overridepublic void onPause() {}@Overridepublic void onDestroy() {}@Overridepublic void onRestart() {}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {}@Overridepublic void onClick(View v) {}
}
public class TitleModel extends SimpleBaseModel<LayoutTitleBinding>{public TitleModel(LayoutTitleBinding binding, Activity context) {super(binding, context);}public void setTitle(String str){binding.tx.setText(str);}private void func(){//需要重复的业务逻辑}@Overridepublic void onClick(View v) {}}
public class TitleModel2 extends SimpleBaseModel{public TitleModel2(ViewBinding binding, Activity context) {super(binding, context);}public void setTitle(){if(binding instanceof LayoutTitleBinding) {((LayoutTitleBinding) binding).tx.setText("test");}}private void func(){//需要重复的业务逻辑}@Overridepublic void onClick(View v) {}}
public class MainActivity extends BaseActivity<ActivityMainBinding,MainModel> {@Overrideprotected void onPrepare() {}@Overrideprotected ActivityMainBinding getBinding() {return ActivityMainBinding.inflate(getLayoutInflater());}@Overrideprotected MainModel getModel() {return new MainModel(binding,this);}
}
最后贴出adapter和fragment的写法和用法,利用泛型可以节省大量的代码
public abstract class BaseAdapter<T, B extends ViewBinding> extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {protected OnItemClick onItemClick;protected List<T> mDatas;protected Context context;public List<T> getmDatas() {return mDatas;}public void setmDatas(List<T> mDatas) {this.mDatas = mDatas;}public BaseAdapter(Context context) {this.context = context;}public BaseAdapter(Context context, List<T> mDatas) {this.mDatas = mDatas;this.context = context;}public OnItemClick getOnItemClick() {return onItemClick;}public void setOnItemClick(OnItemClick onItemClick) {this.onItemClick = onItemClick;}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {LayoutInflater inflater = LayoutInflater.from(context);B binding = setBinding(inflater, parent);ViewHolder<B> viewHolder = new ViewHolder<B>(binding.getRoot());viewHolder.setBinding(binding);if(onItemClick!=null){viewHolder.setOnItemClick(onItemClick);}return viewHolder;}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {ViewHolder<B> myholder=(ViewHolder<B>) holder;onBindHolder(myholder,position);}protected abstract void onBindHolder(ViewHolder<B> holder, int position);@Overridepublic int getItemViewType(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}protected abstract B setBinding(LayoutInflater inflater, ViewGroup parent);@Overridepublic int getItemCount() {return mDatas == null ? 0 : mDatas.size();}public static class ViewHolder<B extends ViewBinding> extends RecyclerView.ViewHolder implements View.OnClickListener {protected OnItemClick onItemClick;public B binding;public OnItemClick getOnItemClick() {return onItemClick;}public void setOnItemClick(OnItemClick onItemClick) {this.onItemClick = onItemClick;}public B getBinding() {return binding;}public void setBinding(B binding) {this.binding = binding;}public ViewHolder(View itemView) {super(itemView);}public void setClick(View... views){if(onItemClick!=null) {for (View view : views) {view.setOnClickListener(this);}}}@Overridepublic void onClick(View v) {onItemClick.onClick(v,getAdapterPosition());}}public static interface OnItemClick{void onClick(View view, int position);}}
public class TestAdapter extends BaseAdapter<String,ItemTestBinding> {public TestAdapter(Context context, List <String>mDatas) {super(context, mDatas);}@Overrideprotected void onBindHolder(ViewHolder<ItemTestBinding> holder, int position) {holder.getBinding().tx.setText(mDatas.get(position));}@Overrideprotected ItemTestBinding setBinding(LayoutInflater inflater, ViewGroup parent) {return ItemTestBinding.inflate(inflater,parent,false);}
}
public abstract class BaseFragment<T extends ViewBinding,M extends BaseModel> extends Fragment {protected T binding;protected M model;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {onPrepare();binding=getBinding(inflater,container,savedInstanceState);model=getModel();return binding.getRoot();}protected abstract void onPrepare();protected abstract T getBinding(LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState);protected abstract M getModel();
}
源码已经上传github
地址:https://github.com/roofroot/test_view_binding
这篇关于ViewBinding与MVVM框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!