mvvm

1.配置

 * 1.首先在build.gradle添加 
		
		android {
		    ....
		    dataBinding {
		        enabled = true
		    }
		}

    * 2.注意 
            
            在Activity中使用DataBindingUtil之前,必须先在Manifest中先注册Activity,否则可能找不到包
2.基础 
    * 1.布局文件Root元素使用Layout

    * 2.配置Data节点

!xml  
		<layout xmlns:android="http://schemas.android.com/apk/res/android">s
			    <data>
			
			        <import type="com.siyan.databinder.entity.Person" />
			
			        <variable
			            name="p"
			            type="Person" />
			    </data>
		    <LinearLayout
		        android:layout_width="match_parent"
		        android:layout_height="match_parent"
		        android:orientation="vertical">
	
		        <TextView
		            android:layout_width="wrap_content"
		            android:layout_height="wrap_content"
		            android:text="@{p.name}" />
	
		    </LinearLayout>
		</layout>
	```
	刚才在 build.gradle 中添加的那个插件 - com.android.databinding会根据xml文件的名称 Generate 一个继承自 ViewDataBinding 的类。
	
	例如,这里 xml 的文件名叫 activity_Main.xml,那么生成的类就是 ActivityMainBinding

3.代码中绑定

 ActivityMainBinding 类是自动生成的,所有的 set 方法也是根据 variable name属性生成的。例如,我们在定义了一个name=“p” 那么就会生成对应的set 方法setP(Person person);
                ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
                Person person = new Person("haha", "18");
                binding.setP(person);   

4.数据对象

public class Person {
	    private String name;
	    private String age;
	
	    public Person(String name, String age) {
	        this.name = name;
	        this.age = age;
	    }
	
	    public String getName() {
	        return name;
	    }
	
	    public String getAge() {
	        return age;
	    }
	}

5.定义 Variable:其中 type 属性就是我们在 Java 文件中定义的 Person 类。

//俩种引用->类的方式
		  <data>
					//此处相当于导向操作,和Java Import是一个性致
			        <import type="com.siyan.databinder.entity.Person" />
					//因为已经导包,type属性等价于类名,name属性等价于类的变量名
			        <variable
			            name="p"
			            type="Person" />
		</data>

		<data>
     				//此处没有导包操作,type属性需要类的全类名,name等价于类的变量名
					<variable
					 	name="user" 
						type="com.liangfeizc.databindingsamples.basic.User" />
		</data>
		
		//注意:
				java.lang.* 包中的类会被自动导入,可以直接使用,例如要定义一个 String 类型的变量
		<data>
					<variable
					 	name="name" 
						type="String" />
		</data>

6.使用 Variable  :@{name.属性名或者方法名} 使用就像Java代码中调用属性或者方法名。注:@{}是必备的格式

 <TextView
		            android:layout_width="wrap_content"
		            android:layout_height="wrap_content"
		            android:text="@{p.name}" />

7.高级用法

使用类方法
		* 静态方法调用
			* 1.首先创建Java static方法
				```
					#!Java
					  public static String getTime(){
					        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
					        Date date = new Date();
					        return format.format(date);
		    		  }
		
				```
			* 2.data节点导入
				```
					#!xml
					<import type="com.cj.databinding.utils.Utils" />
					
				```
			* 3.Xml中使用
				@{Utils.getTime()} 使用起来 和Java调用非常的像
				```
					#!xml
					
	                <TextView
	                    android:layout_width="wrap_content"
	                    android:layout_height="wrap_content"
	                    android:layout_marginTop="10dp"
	                    android:text="@{Utils.getTime()}"
	                    android:textSize="12sp" />

				```
			* 4.调用带参数的方法
				android:text="@{Utils.Gcontent(person.age)}" 
				android:text='@{Utils.Gcontent("haha")}'
				android:text='@{Utils.Gcontent(1314)}'
类型重名
		如果我们在data节点导入了俩个同名的类型怎么办?
		```
			#!xml
				<data>
					//注意结尾处的包名是相同的,如果类名也相同的话,需要使用 alias给重名的类型 起一个别名,在type使用的时候就需要使用alias起的别名
			        <import type="com.siyan.databinder.entity.Person" />
					<import type="com.cj.entity.Person" alias="HahaPerson" />
			
			        <variable
			            name="p"
			            type="Person" />

			        <variable
			            name="hp"
			            type="HahaPerson" />
			    </data>
三元运行符
			android:text="@{person.displayName ?? person.Name}"
			等价
			android:text="@{person.displayName != null ? person.displayName : person.Name}"
事件绑定 
			
			DataBinding也提供了事件绑定,使用和静态方法差不多:不同点就是参数必须是(View v)对象
			注意:com.android.databinding:dataBinder:1.0-rc0 --->是无法使用 事件绑定的
			下面我们来看看如何给Button设置点击事件:
			
				```
					#!Java

					    public void getToast(View v){
        						Toast.makeText(v.getContext(), "绑定事件", Toast.LENGTH_SHORT).show();
    					}

				```

				```
					#!xml

						<data>
							<import type="com.cj.databinding.click.BindingClick"/>
						</data>
					
					   <Button
			             android:onClick="@{bdclick.showToast}"
			             android:layout_width="match_parent"
			             android:layout_height="wrap_content"
			             android:text="@string/click_showToast" />
数据对象
		我们学会了通过binding为我们的变量设置数据,但是不知道你有没有发现一个问题,当我们数据改变的时候会怎样?数据是跟随着改变呢?还是原来的数据呢?这里告诉你答案:很不幸,显示的还是原来的数据?那有没有办法让数据源发生变化后显示的数据也随之发生变化?先来想想ListView是怎么做的, ListView的数据是通过Adapter提供的,当数据发生改变时,我们通过notifyDatasetChanged通过UI去改变数据,这里面的原理其实就是内容观察者,庆幸的是DataBinding也支持内容观察者,而且使用起来也相当方便!

		BaseObservable 

		我们可以通过Observable的方式去通知UI数据已经改变了,当然了,官方为我们提供了更加简便的方式BaseObservable,我们的实体类只需要继承该类,稍做几个操作,就能轻松实现数据变化的通知。如何使用呢? 首先我们的实体类要继承BaseObservale类,第二步在Getter上使用注解@Bindable,第三步,在Setter里调用方法notifyPropertyChanged,第四步,完成。就是这么简单,下面我们来实际操作一下。

		```
			#!Java
			public class Person extends BaseObservable{
			    private String name;
			    private String age;
			
			    public Person(String name, String age) {
			        this.name = name;
			        this.age = age;
			    }
			    @Bindable
			    public String getName() {
			        return name;
			    }
			    @Bindable
			    public String getAge() {
			        return age;
			    }
			
			    public void setName(String name) {
			        this.name = name;
			        notifyPropertyChanged(BR.name);
			    }
			
			    public void setAge(String age) {
			        this.age = age;
			        notifyPropertyChanged(BR.age);
			    }
			}

			观察getName方法,我们使用了@Bindable注解,观察setName,我们调用了notifyPropertyChanged方法,这个方法还需要一个参数,这个参数是BR,BR参数类似于R.java,保存了我们所有变量的引用地址,这里我们使用了name。

			public void click(View view) {
       			 mPerson.setName("黑马");
    		}
			
		``` 
		ObservableFields家族 

		上面使用BaseObservable已经非常容易了,但是google工程师还不满足,继续给我们封装了一系列的ObservableFields,这里有ObservableField,ObservableBoolean,ObservableByte,ObservableChar,ObservableShort,ObservableInt,ObservableLong,ObservableFloat,ObservableDouble,ObservableParcelable
		ObservableFields的使用方法就更加简单了,例如下面代码:
		```
			#!Java
			public class People {
			    public ObservableField<String> name = new ObservableField<>();
			    public ObservableInt age = new ObservableInt();
			}

		```
		只有二个ObservableField变量,并且没有getter和setter,因为我们不需要getter和setter。 
		
		```
			#!xml

					<data>
						 <import type="com.siyan.databinder.entity.Person" />
					<data>
			        <TextView
			            android:layout_width="wrap_content"
			            android:layout_height="wrap_content"
			            android:text="@{people.name}"/>
			#!Java
				//那怎么赋值和取值呢?这些ObservableField都会有一对get和set方法,所以使用起来也很方便了
				mPeople = new People();
				binding.setPeople(mPeople);
				mPeople.name.set("people");
				mPeople.age.set(19);

		```
		Observable Collections 
		
		既然普通的变量我们有了ObservableFields的分装,那集合呢?当然也有啦,来看着两个:ObservableArrayMap,ObservableArrayList。使用和普通的Map、List基本相同






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值