Android MVVM架构模式 详解和综合运用(四)
来源:互联网 发布:c语言超市管理系统 编辑:程序博客网 时间:2024/06/07 02:31
DataBinding结合RecyclerView使用
在日常的开发中,使用最频繁的组件莫过于列表控件了,例如RecyclerView。DataBinding库也添加了对RecyclerView的adapter的支持,因为adapter是用来管理和分配RecyclerView中数据的组件。
使用DataBinding来开发RecyclerView很简单,首先创建一个item的布局,在这个布局中声明一个user变量:
<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="user" type="bean.User"/> </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:textColor="@android:color/black" android:text="@{user.name}" tools:text="Jason"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:textColor="@android:color/darker_gray" android:text="@{String.valueOf(user.age)}" tools:text="12"/> </LinearLayout></layout>
然后创建一个适配器ListAdapter,只需要继承RecyclerView的Adapter即可,重点在ViewHolder的创建。我们在ListAdapter创建了一个静态类ListHolder,这个ListHolder使用了上面布局自动生成的ListItemBinding类,在create方法中初始化binding,并解析布局,但是却没有引用到任何布局名,原因就是ListItemBinding中已经封装了它绑定的布局名了。然后在super父类方法中初始化,从binding的getRoot方法中获取item布局。最后在bindTo方法中绑定每个item的数据源,注意必须调用executePendingBindings。例如:
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListHolder>{ private List<User> data; public ListAdapter(ArrayList<User> list){ this.data=list; } @Override public ListHolder onCreateViewHolder(ViewGroup parent, int viewType) { return ListHolder.create(LayoutInflater.from(parent.getContext()),parent); } @Override public void onBindViewHolder(ListHolder holder, int position) { holder.bindTo(data.get(position)); } @Override public int getItemCount() { return data.size(); } static class ListHolder extends RecyclerView.ViewHolder{ private ListItemBinding binding; public static ListHolder create(LayoutInflater inflater,ViewGroup parent){ ListItemBinding binding=ListItemBinding.inflate(inflater,parent,false); return new ListHolder(binding); } private ListHolder(ListItemBinding binding) { super(binding.getRoot()); this.binding=binding; } public void bindTo(User user){ binding.setUser(user); binding.executePendingBindings(); } }}
executePendingBindings方法是用来通知View立即刷新视图的,因为当变量或者observable数据源改变的时候,binding会在下一帧才开始刷新View,这可能会导致延迟,因为当快速刷新列表的时候,对View的刷新必须立即实时的。所以为了强制系统对View进行刷新,必须在设置数据源后调用binding.executePendingBindings()。
然后在Activity中对recyclerView绑定adapater就可以了,和平时的使用方法一毛一样。
首先是activity的布局文件:
<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/ListActivity_RecyclerView" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout></layout>
然后在activity中使用binding.ID名来获取在layout中声明id的控件,而不用findViewById了,炒鸡方便:
public class ListActivity extends BaseActivity { private ActivityListBinding binding; private ListAdapter adapter; @Override protected void initView() { binding= DataBindingUtil.setContentView(this, R.layout.activity_list); } @Override protected void initData() { ArrayList<User> data=new ArrayList<>(); data.add(new User("Jason",23)); data.add(new User("Sakura",20)); data.add(new User("bilibi",18)); data.add(new User("Afun",17)); data.add(new User("Tom",26)); adapter=new ListAdapter(data); LinearLayoutManager manager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false); binding.ListActivityRecyclerView.setLayoutManager(manager); binding.ListActivityRecyclerView.setAdapter(adapter); } @Override protected void initListener() { }}
可以在后台子线程中改变任何一个非集合model对象中的数据,DataBinding库会运行时局部化对象中的变量或属性以避免并发问题的发生。
转换器
当在Binding表达式@{ }中返回一个对象时,例如@{ user },DataBinding库会去寻找与这个对象的数据类型一致的View属性的setter方法,例如android:text=”@{ user.age},age为int型时,会去寻找setText(int)的方法。
当对象中属性为Object类型时,DataBinding会根据原始setter方法参数类型来强制类型转换Object, 例如在people对象中有一个Object属性:
public class People extends BaseObservable{ private String firstName; private String lastName; private Object convert; @Bindable public String getFirstName(){ return firstName; } @Bindable public String getLastName(){ return lastName; } public void setFirstName(String firstName){ this.firstName=firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName){ this.lastName=lastName; notifyPropertyChanged(BR.lastName); } public Object getConvert() { return convert; } public void setConvert(Object convert) { this.convert = convert; }}
在Layout布局文件的TextView中关联这个people对象,例如:
<TextView android:textSize="14sp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@{people.convert}" tools:text="Jason"/>
setText(CharSequence)中的参数类型为CharSequence,那么这个people.convert的Object类型的对象会被强制类型转换为CharSequence。
当然我们也可以在@{ }表达式中进行显式强制类型转换,例如:
android:text="@{(String)people.convert}"android:text="@{String.valueOf(people.convert)}"
有时在Binding@{ }表达式中特定类型之间的转换是自动的,例如,设置View的background属性:
<View android:background="@{isError ? @color/red : @color/white}" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
android:background属性的参数类型为Drawable,但是这里@color/red为int类型。但是DataBinding自动把int类型转换为了ColorDrawable对象类型。这个转换系统已经帮我们实现了,主要是使用@BindingConversion 注解一个静态方法来实现的,例如:
@BindingConversionpublic static ColorDrawable convertColorToDrawable(int color) { return new ColorDrawable(color);}
注意表达使中不支持混用的数据类型,例如 下面的做法是错误的:
<View android:background="@{isError ? @drawable/error : @color/white}" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
- Android MVVM架构模式 详解和综合运用(四)
- Android MVVM架构模式 详解和综合运用(一)
- Android MVVM架构模式 详解和综合运用(二)
- Android MVVM架构模式 详解和综合运用(三)
- Android MVVM架构模式(一)
- 设计模式在综合前置中的运用(四)--原型模式
- Android架构模式:MVC & MVP & MVVM
- 浅谈 MVC、MVP 和 MVVM 架构模式
- Android中的MVC、MVP、MVVM模式的运用
- Android中MVC、MVP、MVVM模式的运用
- Android中MVC、MVP、MVVM模式的运用 (续)
- MVVM 架构模式分析
- MVVM架构模式
- Android App的三种架构模式MVC,MVP和MVVM
- 【项目架构】Android MVP 和MVVM框架模式 学习实例Demo之mvp篇
- Android App的三种架构模式MVC,MVP和MVVM
- Hibernate综合运用内部留言本(四)
- Android笔记(28)MVVM架构过程
- android事件分发
- CentOS7安装问题
- preventDefault()、stopPropagation()、return false 之间的区别
- AbstractPlatformTransactionManager(Spring事务底层核心类)API讲解翻译
- mysql jdbc连接服务器上数据库却显示本地ip拒绝访问
- Android MVVM架构模式 详解和综合运用(四)
- 解决mySQL占用内存超大问题
- 逗比青年的2016
- 设置漂亮的eclipse主题(Theme)风格
- 各大公司Java后端开发面试题总结
- 选择排序
- 用七牛做图床-同步工具qrsbox
- 生产环境构建指南:Web应用——部署
- Linux试题3