android MVVM框架学习总结(一)
2018-03-31 15:12
393 查看
android MVVM框架学习总结
1.简单的数据绑定示例
2.事件处理
3. Layout细节
在标签中 描述了一个变量user,它对应的类型为”com.example.User”
布局中使用“@ { }”语法来书写表达式。如为TextView的文本设置成user. firstName.
(2) 数据对象这样写
在数据绑定中,访问@{user.firstName},那么默认就会访问同名的属性firstName,或对应的getFirstName方法。
(3)数据绑定
默认情况下,绑定类将基于布局文件的名称来产生
如布局文件为main_activity.xml,这样生成的类是 MainActivityBinding
如下设置Activity的contentView:
上文说,在xml中用表达式可以获取数据,那么同样的,在代码中也可以设置数据,如这里的:binding.setUser(user);
还可以使用inflate的方式来获取生成数据绑定类:
如果是在一个adapter中来使用,那么可以如下:
1. 方法引用:可以引用符合listener 任意方法签名规则的方法。
2. 监听器绑定:使用lambda表达式。
1.方法引用
比如定义一个符合OnClickListener#onClick(View view)方法参数签名规则的方法:
如下在xml中绑定并使用:
2.监听器绑定
表达式使用的方法就可以定义的比较随意了,不用像”方法引用”那样遵循特定规则,如一个方法
xml中使用它
像上面,我们并没有定义onClick(android.view.View) 参数view。监听器绑定,允许我们忽略所有的参数。如果想要使用参数,可以忽略参数类型,随意定义一个名字。监听器绑定还有很多灵活的写法,可以参考官方文档。
1) 在标签中,import 一些class,就像在java 代码中一样
如:
2) 当类名过长或者有类名称冲突,其中一个类可以重命名一个别名
3) 也可以在表达式中运用静态属性或方法,使用MyStringUtils.capitalize():
示例代码
(2)可以定义多个标签
这些variable变量在编译时会进行类型检查,如果一个variable实现了Observable接口或是一个Observable的collection,那就需要在type中声明;如果不是一个Observable的实现,那么该variable就不会被观察到.
(3)自定义绑定 class names
默认情况下,基于布局文件的名称而生成绑定类,开头大写,然后移除下划线,再加上后缀”Binding”。这个类将被放置在一个数据绑定包中,该包位于moudle包下。例如, 布局文件contact_item.xml将生成ContactItemBinding。如果moudle的包名为com.example.my.app, 那么它将被放置在com.example.my.app.databinding下,通过调整data元素的class属性,绑定类可以重命名或放置在不同的包。
这会生成在moudle下的databinding包下,如果要生成moudle包下,可以使用”.”前缀:
在下面这种情况下,ContactItem直接生成在模块包下。可以使用任何完整的包路径:
(4)include
variables可以传递给使用了include标签的子布局中,如
如上,在name.xml和contract.xml中都可以使用变量user了
不支持在merge下直接使用include的情形。
(5)表达式语言
1)共同的特征
表达式语言看起来很像Java表达式。如下这些都是相同的:
例:
2)不支持的操作符
3)合并null操作符
如下使用 “??” 操作符
等价于
4)属性引用
如下,user有getLastName(),可以简单引用:
5)NullPointerException处理
数据绑定代码会自动检查null值,避免NullPointerException。例如String类型默认为null, Int类型默认0.
6)集合
一般的集合都可以使用”[]”操作符: arrays, lists, sparse lists, and maps。例
7)字符串引用
如下,可以使用单引号在属性值上,用双引号在字符串字面值上:
也可以反过来
8)资源
可以使用正常的访问资源的表达式语法:
可以为格式字符串和复数提供参数:
一些资源需要显示的引用
1.简单的数据绑定示例
2.事件处理
3. Layout细节
android MVVM框架学习总结
1.简单的数据绑定示例
(1)布局文件这样写<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.User"/> </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.firstName}"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.lastName}"/> </LinearLayout> </layout>
在标签中 描述了一个变量user,它对应的类型为”com.example.User”
布局中使用“@ { }”语法来书写表达式。如为TextView的文本设置成user. firstName.
(2) 数据对象这样写
public class User { public final String firstName; public final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } }
在数据绑定中,访问@{user.firstName},那么默认就会访问同名的属性firstName,或对应的getFirstName方法。
(3)数据绑定
默认情况下,绑定类将基于布局文件的名称来产生
如布局文件为main_activity.xml,这样生成的类是 MainActivityBinding
如下设置Activity的contentView:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity); User user = new User("Test", "User"); binding.setUser(user); }
上文说,在xml中用表达式可以获取数据,那么同样的,在代码中也可以设置数据,如这里的:binding.setUser(user);
还可以使用inflate的方式来获取生成数据绑定类:
MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());
如果是在一个adapter中来使用,那么可以如下:
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); //or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
2.事件处理
可以在xml中编写表达式处理事件。比如 View.OnLongClickListener有一个方法为onLongClick(),那么它对应的事件就是android:onLongClick。当绑定事件后,会自动将该listener绑定在View上。处理事件有两种方法,1. 方法引用:可以引用符合listener 任意方法签名规则的方法。
2. 监听器绑定:使用lambda表达式。
1.方法引用
比如定义一个符合OnClickListener#onClick(View view)方法参数签名规则的方法:
public class MyHandlers { public void onClickFriend(View view) { ... } }
如下在xml中绑定并使用:
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="handlers" type="com.example.Handlers"/> <variable name="user" type="com.example.User"/> </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.firstName}" android:onClick="@{handlers::onClickFriend}"/> </LinearLayout> </layout>
2.监听器绑定
表达式使用的方法就可以定义的比较随意了,不用像”方法引用”那样遵循特定规则,如一个方法
public class Presenter { public void onSaveClick(Task task){} }
xml中使用它
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="task" type="com.android.example.Task" /> <variable name="presenter" type="com.android.example.Presenter" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{() -> presenter.onSaveClick(task)}" /> </LinearLayout> </layout>
像上面,我们并没有定义onClick(android.view.View) 参数view。监听器绑定,允许我们忽略所有的参数。如果想要使用参数,可以忽略参数类型,随意定义一个名字。监听器绑定还有很多灵活的写法,可以参考官方文档。
3. Layout细节
(1) import1) 在标签中,import 一些class,就像在java 代码中一样
如:
<import type="android.view.View"/>
2) 当类名过长或者有类名称冲突,其中一个类可以重命名一个别名
<import type="com.grandstream.gsmarket.R.string" alias="Strings"/> <import type="android.view.View"/> <import type="com.example.real.estate.View" alias="EsView"/>
3) 也可以在表达式中运用静态属性或方法,使用MyStringUtils.capitalize():
<data> <import type="com.example.MyStringUtils"/> <variable name="user" type="com.example.User"/> </data> … <TextView android:text="@{MyStringUtils.capitalize(user.lastName)}" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
示例代码
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" > <data> <variable name="viewmodel" type="com.grandstream.gsmarket.appdetail.AppDetailItemViewModel" /> <import type="android.view.View"/> <import type="com.grandstream.gsmarket.R.string" alias="Strings"/> </data> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v7.widget.AppCompatTextView android:id="@+id/download_count_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:singleLine="true" android:textColor="#999999" android:textSize="36px" android:text='@{viewmodel.getContext().getString(Strings.download) + viewmodel.downloadCount}'/> </LinearLayout>
(2)可以定义多个标签
这些variable变量在编译时会进行类型检查,如果一个variable实现了Observable接口或是一个Observable的collection,那就需要在type中声明;如果不是一个Observable的实现,那么该variable就不会被观察到.
<data> <import type="android.view.View" /> <variable name="view" type="com.grandstream.gsmarket.apps.ApkListFragment" /> <variable name="viewmodel" type="com.grandstream.gsmarket.apps.AppsViewModel" /> </data>
(3)自定义绑定 class names
默认情况下,基于布局文件的名称而生成绑定类,开头大写,然后移除下划线,再加上后缀”Binding”。这个类将被放置在一个数据绑定包中,该包位于moudle包下。例如, 布局文件contact_item.xml将生成ContactItemBinding。如果moudle的包名为com.example.my.app, 那么它将被放置在com.example.my.app.databinding下,通过调整data元素的class属性,绑定类可以重命名或放置在不同的包。
<data class="ContactItem"> ... </data>
这会生成在moudle下的databinding包下,如果要生成moudle包下,可以使用”.”前缀:
<data class=".ContactItem"> ... </data>
在下面这种情况下,ContactItem直接生成在模块包下。可以使用任何完整的包路径:
<data class="com.example.ContactItem"> ... </data>
(4)include
variables可以传递给使用了include标签的子布局中,如
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto"> <data> <variable name="user" type="com.example.User"/> </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/name" bind:user="@{user}"/> <include layout="@layout/contact" bind:user="@{user}"/> </LinearLayout> </layout>
如上,在name.xml和contract.xml中都可以使用变量user了
不支持在merge下直接使用include的情形。
(5)表达式语言
1)共同的特征
表达式语言看起来很像Java表达式。如下这些都是相同的:
Mathematical + - / * % String concatenation + Logical && || Binary & | ^ Unary + - ! ~ Shift >> >>> << Comparison == > < >= <= instanceof Grouping () Literals - character, String, numeric, null Cast Method calls Field access Array access [] Ternary operator ?:
例:
android:text="@{String.valueOf(index + 1)}" android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}" android:transitionName='@{"image_" + id}'
2)不支持的操作符
this、new、super 如这些,还是只能在java类中使用
3)合并null操作符
如下使用 “??” 操作符
android:text="@{user.displayName ?? user.lastName}"
等价于
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
4)属性引用
如下,user有getLastName(),可以简单引用:
android:text="@{user.lastName}"
5)NullPointerException处理
数据绑定代码会自动检查null值,避免NullPointerException。例如String类型默认为null, Int类型默认0.
6)集合
一般的集合都可以使用”[]”操作符: arrays, lists, sparse lists, and maps。例
<data> <import type="android.util.SparseArray"/> <import type="java.util.Map"/> <import type="java.util.List"/> <variable name="list" type="List<String>"/> <variable name="sparse" type="SparseArray<String>"/> <variable name="map" type="Map<String, String>"/> <variable name="index" type="int"/> <variable name="key" type="String"/> </data> … android:text="@{list[index]}" … android:text="@{sparse[index]}" … android:text="@{map[key]}"
7)字符串引用
如下,可以使用单引号在属性值上,用双引号在字符串字面值上:
android:text='@{map["firstName"]}'
也可以反过来
android:text="@{map[`firstName`}" android:text="@{map['firstName']}"
8)资源
可以使用正常的访问资源的表达式语法:
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"
可以为格式字符串和复数提供参数:
android:text="@{@string/nameFormat(firstName, lastName)}" android:text="@{@plurals/banana(bananaCount)}"
一些资源需要显示的引用
Type | Normal Reference | Expression Reference |
---|---|---|
String[] | @array | @stringArray |
int[] | @array | @intArray |
TypedArray | @array | @typedArray |
Animator | @animator | @animator |
StateListAnimator | @animator | @stateListAnimator |
color int | @color | @color |
ColorStateList | @color | @colorStateList |
相关文章推荐
- android MVVM框架学习总结(三)
- Android MVVM框架学习总结(二)
- Android MVVM框架学习总结(四)
- android快速开发框架 可以一个个学习总结
- Android 框架 MVC、MVP、MVVM学习笔记
- Android系统框架学习总结
- 【项目架构】Android MVP 和MVVM框架模式 学习实例Demo之mvp篇
- android(安卓)开源框架学习总结
- Android二维码ZXing开源框架的学习总结
- Android网络框架volley学习(十一)volley源码解析总结
- nio socket 及其开源框架MINA学习总结(一)
- Android画图学习总结(一)——类的简介
- Android画图学习总结(二)——Bitmap
- Android画图学习总结(四)——Animation(中)
- Android画图学习总结(二)——Bitmap
- Android画图学习总结(四)——Animation(下)
- Android画图学习总结(四)——Animation(下)
- Android画图学习总结(一)——类的简介
- Android学习基础要点总结
- nio socket 及其开源框架MINA学习总结(一)