DataBinding初识

 DataBinding-MVVM设计模式:

       MVVM 可以算是 MVP的升级版,将 Presenter 改名为 ViewModel。关键在于 View和Model的双向绑定,当 View 有用户输入后,ViewModel 通知 Model 更新数据,同理 Model 数据更新后,ViewModel 通知 View 更新。

一  环境要求:

  • Android Studio 版本在 1.3以上

  • Gradle 的版本要在 1.5.0-alpha1 以上

  • 需要在 Android SDK manager 中下载 Android Support repository


然后在对应的 Module build.gradle 中添加:


android {
   ....    dataBinding {        enabled =true    } }

二 Databinding 当简单使用
(1)创建对象
public class User extends BaseObservable {
    private String name;
    private boolean isAdult;
   @Bindable
    public String getName() {
        return name;

    }

    public void setName(String name) {
      
        this.name = name;
    }
    @Bindable
    public boolean isAdult() {
        return isAdult;
    }

    public void setAdult(boolean adult) {
       
        isAdult = adult;
    }

 
}

 创建好对象之后 接下来 就是在xml 设置进去啦

(1)建立xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
 
    >
    <data>

  
        <variable
            name="user"
            type="com.example.willer.databindingdemo.data.User"></variable>
       
    </data>
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.name}"
        />
  
</LinearLayout>


</layout>

需要值得注意的是,根节点以 layout 定义 而且是不需要设置宽高 属性当哦,节点data 可以认为是数据来源,通过代码中直接设置,简简单单当做完以上两步之后,就可以在代码中使用啦

(3)代码中使用

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        final User user = new User();

        user.setName("willer");
        user.setAdult(true);
   

        binding.setUser(user);
    }

经过简单三步之后,最简单的databinding使用就已经完成了,是不是很简单呢。 接下来我想说明一些在第一次使用dataBinding中的坑,在刚开使用的时候,始终疑惑,为什么我的代码生成不出 ActivityMainBinding  这个类,即这行代码

        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
后来去stackOverflow上查找了一下问题,最后只需要clean project 才生成,希望能帮助遇坑当小伙伴们,这仅仅是遇见当坑之一,稍微说明其他当一些坑。需要说明一下, ActivityMainBinding是自动生成当。

(3)设置点击事件


创建一个对象

public class MyHandlers {
    public void onClickFriend(View view) { ... }
}
<?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.name}"
           android:onClick="@{handlers::onClickFriend}"/>
   </LinearLayout>
</layout>
另外一种用法

public class Presenter {
    public void onSaveClick(Task task){}
}
  <?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>

(4)消除空指针

自动生成的 DataBinding 代码会检查 null,避免出现NullPointerException

例如在表达式中 @{user.phone}如果user == null 那么会为 user.phone 设置 默认值null 而不会导致程序崩溃(基本类型将赋予默认值如 int为0,引用类型都会赋值null)。

(5)导包

跟Java中的用法相似,布局文件中支持 import 的使用,原来的代码是这样:


<data>
    <variable name="user" type="com.example.gavin.databindingtest.User" />
</
data>


使用 import 后可以写成这样:


<data>
    <import type="com.example.gavin.databindingtest.User"/>
    <variable
        name="user"
        type="User" />
</
data>


遇到 相同的类名 的时候:




使用 alias 设置别名,这样 user 对应的就是 com.example.gavin.databindingtest.UsermcUser 就对应com.example.gavin.mc.User,然后:


<TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="@{user.firstName}"/>
(6)三元运算


User 中添加 boolean类型 isStudent属性,用来判断是否为学生:




注意:需要用到双引号的时候,外层的双引号改成单引号。


还可以这样用:



这里用到的 View 需要在 data 中声明:


<data>
    <import type="android.view.View"/>
</data>


注意:android:visibility="@{user.isStudent ? View.VISIBLE : View.GONE}",可能会被标记成红色,不用管它编译会通过的。


??


除了常用的操作法,另外还提供了一个 null 的合并运算符号 ??,这是一个三目运算符的简便写法。


contact.lastName ?? contact.name


相当于:


contact.lastName != null ? contact.lastName : contact.name


所支持的操作符如下:


数学运算符 + - / * %
字符串拼接 +
逻辑运算 && ||
二进制运算 & | ^
一元运算符 + - ! ~
位运算符 >> >>> <<
比较运算符 == > < >= <=
instanceof
Grouping ()
文字 - character, String, numeric, null
类型转换 cast
方法调用 methods call
字段使用 field access
数组使用 [] Arrary access
三元运算符 ? :



(7) 图片当加载

除了文字的设置,网络图片的显示也是我们常用的。来看看 Data Binding 是怎么实现图片的加载的。

/**
 * 使用ImageLoader显示图片
 * @param imageView
 * @param url
 */
@BindingAdapter({"bind:imageUrl"})
public static void imageLoader(ImageView imageView, String url) {
    Glide.with(imageView.getContext()).load(url).into(imageView);
}
需要值得注意当是 上面这个方法必须是静态当 否则会报错

首先要提到 BindingAdapter注解,这里创建了一个类,里面有显示图片的方法:

这里只用了 bind 声明了一个 imageUrl 自定义属性,等下在布局中会用到。


这个类中只有一个静态方法 imageLoader,里面有两参数,一个是需要设置图片的 view,另一个是对应的 Url,这里使用了
Glide库加载图片。


看看它的布局是什么样的吧:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <data>
   <variable name="imageUrl"type="String"></variable>
    </data>
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


      <ImageView
          app:imageUrl="@{imageUrl}"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" />
</LinearLayout>


</layout>
注意哦,app这个属性不要忘记导入
    xmlns:app="http://schemas.android.com/apk/res-auto"

最后在 MainActivity 中绑定下数据就可以了:binding.setImageUrl("url");

是不是很方便,不用关心他是什么时候调用imageLoader这个静态方法,databinding直接会内部调用

(7)数据的绑定

a)Observable 对象

实现android.databinding.Observable接口的类可以允许附加一个监听器到Bound对象以便监听对象上的所有属性的变化。

Observable接口有一个机制来添加和删除监听器,但通知与否由开发人员管理。为了使开发更容易,一个BaseObservable的基类为实现监听器注册机制而创建。Data实现类依然负责通知当属性改变时。这是通过指定一个Bindable注解给getter以及setter内通知来完成的。

private static class User extends BaseObservable {
   private String firstName;
   private String lastName;
   @Bindable
   public String getFirstName() {
       return this.firstName;
   }
   @Bindable
   public String getFirstName() {
       return this.lastName;
   }
   public void setFirstName(String firstName) {
       this.firstName = firstName;
       notifyPropertyChanged(BR.firstName);
   }
   public void setLastName(String lastName) {
       this.lastName = lastName;
       notifyPropertyChanged(BR.lastName);
   }
}

在编译期间,Bindable注解在BR类文件中生成一个Entry。BR类文件会在模块包内生成。如果用于Data类的基类不能改变,Observable接口通过方便的PropertyChangeRegistry来实现用于储存和有效地通知监听器。

b)Observable 字段

一些小工作会涉及到创建Observable类,因此那些想要节省时间或者几乎没有几个属性的开发者可以使用ObservableFieldsObservableFields是自包含具有单个字段的observable对象。它有所有基本类型和一个是引用类型。要使用它需要在data对象中创建public final字段:

private static class User {
   public final ObservableField<String> firstName =
       new ObservableField<>();
   public final ObservableField<String> lastName =
       new ObservableField<>();
   public final ObservableInt age = new ObservableInt();
}

就是这样,要访问该值,使用set和get方法:

user.firstName.set("Google");
int age = user.age.get();
c)Observable 集合

一些app使用更多的动态结构来保存数据。Observable集合允许键控访问这些data对象。ObservableArrayMap用于键是引用类型,如String

ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);

在layout文件中,通过String键可以访问map:

<data>
    <import type="android.databinding.ObservableMap"/>
    <variable name="user" type="ObservableMap<String, Object>"/>
</data><TextView
   android:text='@{user["lastName"]}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>
<TextView
   android:text='@{String.valueOf(1 + (Integer)user["age"])}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

ObservableArrayList用于键是整数:

ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);

在layout文件中,通过索引可以访问list:

<data>
    <import type="android.databinding.ObservableList"/>
    <import type="com.example.my.app.Fields"/>
    <variable name="user" type="ObservableList<Object>"/>
</data><TextView
   android:text='@{user[Fields.LAST_NAME]}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>
<TextView
   android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

后续的内容 下次补充哈




















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值