数据绑定(data binding )1

数据绑定(Data Binding)-Part1

2015年的Google I/O大会发布了很多新的Android库和工具,Data Binding就是其中之一。在本系列文章中,我们会探索它的强大之处。

值得注意的是:我写这篇文章的时候,Data Binding库正在测试中,所以很多API可能会在发布的时候有所改动。

Data Binding库提供了一个链接待显示数据与UI组件的机制,将原本非常被动的数据变成某种形式的数据源。在本篇文章中我们使用一个非常简单的Twitter客户端作为例子,将Twitter API与Data Binding一起使用。我不会在这里介绍API以及App设计,我仅仅是使用Twitter4J库抽取了你的Twitter主页上50条按时间排序的信息,并将他们展示在RecyclerView中。所有的代码都是公开发布的,你可以放心地使用它理解它。这里面最有意思的就是其中的数据及它们与View绑定的过程。

我们来看看这篇例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

public class Status {

 

    private final String name;

    private final String screenName;

    private final String text;

    private final String imageUrl;

 

    public Status(@NonNull String name, @NonNull String screenName, @NonNull String text, @NonNull String imageUrl) {

        this.name = name;

        this.screenName = screenName;

        this.text = text;

        this.imageUrl = imageUrl;

    }

 

    public String getName() {

        return name;

    }

 

    public String getScreenName() {

        return screenName;

    }

 

    public String getText() {

        return text;

    }

 

    public String getImageUrl() {

        return imageUrl;

    }

}

 

这个类维持了几个需要展示给用户的基本元素,每一个在RecyclerView中的单位都会绑定一个Status对象。它里面的信息可以从twitter4j.Status(由Twitter4j的API获取)中得到,所以我们还要创建一个将twitter4j.Status转化为Status的类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

publicclassStatusMarshaller{

 

    publicList<Status>marshall(List<twitter4j.Status>statuses){

        List<Status>newStatuses=newArrayList<>(statuses.size());

        for(twitter4j.Statusstatus:statuses){

            newStatuses.add(marshall(status));

        }

        returnnewStatuses;

    }

 

    privateStatusmarshall(twitter4j.Statusstatus){

        Useruser=status.getUser();

        returnnewStatus(user.getName(),user.getScreenName(),status.getText(),user.getBiggerProfileImageURL());

    }

}

 

这里没有用到任何技巧,只是一个简单的Java操作,跟Data Binding无关,甚至跟Android也无关。

不过需要指出的是,我们本可以直接将View与twitter4j.Status绑定在一起,这样无疑效率会更高。但是Data
Binding库使用了MVVM(Model-View-ViewModel)设计模式 – Model是twitter4j.Status,View是UI组件,ViewModel是我们的Status对象。ViewModel代表着专门为View设计的一个数据结构,它与View的适配性比Model更好。虽然Model与ViewModel很像,在目前你可能还感觉不出他们的区别,但是随着我们一步步深入下去,我相信你会明白这样设计的深意。

接下来我们看一下RecyclerView的Adapter是怎么设计的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

public class StatusAdapter extends RecyclerView.Adapter<StatusViewHolder> {

    private final List<Status> statuses;

    private final StatusMarshaller marshaller;

 

    public static StatusAdapter newInstance() {

        List<Status> statuses = new ArrayList<>();

        StatusMarshaller marshaller = new StatusMarshaller();

        return new StatusAdapter(statuses, marshaller);

    }

 

    StatusAdapter(List<Status> statuses, StatusMarshaller marshaller) {

        this.statuses = statuses;

        this.marshaller = marshaller;

    }

 

    @Override

    public StatusViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        Context context = parent.getContext();

        LayoutInflater inflater = LayoutInflater.from(context);

        View statusContainer = inflater.inflate(R.layout.status_item, parent, false);

        return new StatusViewHolder(statusContainer);

    }

 

    @Override

    public void onBindViewHolder(StatusViewHolder holder, int position) {

        Status status = statuses.get(position);

        holder.bind(status);

    }

 

    @Override

    public int getItemCount() {

        return statuses.size();

    }

 

    public void setStatuses(List<twitter4j.Status> statuses) {

        this.statuses.clear();

        this.statuses.addAll(marshaller.marshall(statuses));

        notifyDataSetChanged();

    }

 

}

 

终于看到了跟Android有关的地方了吧,实际上没什么特殊的地方——这只是一个基本的RecyclerView.Adapter而已,跟Data Binding其实关系不大。这里面唯一跟MVVM有关系的就是在setStatuses()中将twitter4j.Status转换成Status。我们马上将会在StatusViewHolder中看到怎么进行数据绑定,首先我们来看看layout是怎么定义的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

<?xmlversion="1.0"encoding="utf-8"?>

<layoutxmlns:android="http://schemas.android.com/apk/res/android">

 

  <data>

    <importtype="android.view.View"/>

    <variable

      name="status"

      type="com.stylingandroid.databinding.data.Status"/>

  </data>

 

  <RelativeLayout

    android:id="@+id/status_container"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

 

    <ImageView

      android:id="@+id/status_avatar"

      android:layout_width="64dp"

      android:layout_height="64dp"

      android:layout_alignParentLeft="true"

      android:layout_alignParentStart="true"

      android:layout_alignParentTop="true"

      android:layout_margin="8dip"

      android:contentDescription="@null"/>

 

    <TextView

      android:id="@+id/status_name"

      style="@style/Status.Name"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_alignParentTop="true"

      android:layout_marginTop="8dip"

      android:layout_toEndOf="@id/status_avatar"

      android:layout_toRightOf="@id/status_avatar"

      android:text="@{status.name}"/>

 

    <TextView

      android:id="@+id/status_screen_name"

      style="@style/Status.ScreenName"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:layout_alignBaseline="@id/status_name"

      android:layout_marginLeft="4dip"

      android:layout_marginStart="4dip"

      android:layout_toEndOf="@id/status_name"

      android:layout_toRightOf="@id/status_name"

      android:text="@{&quot;@&quot;
+ status.screenName}"/>

 

    <TextView

      android:id="@+id/status_text"

      style="@style/Status.Text"

      android:layout_width="match_parent"

      android:layout_height="wrap_content"

      android:layout_alignLeft="@id/status_name"

      android:layout_alignParentEnd="true"

      android:layout_alignParentRight="true"

      android:layout_alignStart="@id/status_name"

      android:layout_below="@id/status_name"

      android:maxLines="2"

      android:singleLine="false"

      android:text="@{status.text}"/>

 

  </RelativeLayout>

</layout>

 

这部分代码是Data Binding运作的核心。其中id为status_containerRelativeLayout是一个普通的layout控件,但是它的父控件<layout>就不是那么熟悉了。<layout>是Data
Binding库的一个组件,它含有一个<data>子组件说明了需要绑定的数据对象(在此处为Status),然后我们就可以在此layout中引用该数据对象。

在此布局中TextView的android:text属性值可能跟你正常见到样子的不大一样-它们其实都使用了Status中的getter。使用@{}包装说明这是一个Data
Binding表达式,status.name等同于Java中的status.getName()。这是Data
Binding工作的核心,但是这只是冰山一角,它还有更多有趣的功能值得我们探索。

你看id为status_screen_name的TextView,它的text设置为@{&quot;@&quot;
+ status.screenName}
。你可能看到觉得很困惑,实际上&quot;@&quot;就代表着@,用&quot;将它包装起来是为了防止@被xml转义。这个语句告诉我们Data
Binding语句是很强大的,我们会进一步挖掘它的强大之处。

在定义完layout之后,需要将它和实际数据对象结合,这也是StatusViewHolder做的事:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

publicclassStatusViewHolderextendsRecyclerView.ViewHolder{

    privateStatusItemBindingbinding;

 

    publicStatusViewHolder(ViewitemView){

        super(itemView);

        binding=DataBindingUtil.bind(itemView);

    }

 

    publicvoidbind(Statusstatus){

        binding.setStatus(status);

    }

 

}

 

它比正常使用的ViewHolder(通常用于维持子View对象)更简单一点,在bind()方法中将对象赋予它绑定的layout。首先要注意到我们使用了StatusItemBinding,可以通过DataBindingUtil.bind()函数获取到它,这个函数及StatusItenBinding类都是Data
Binding库生成的。

在下一章中我们会讨论更多的细节,不过此处我们已经有一个基本的应用能够让你对data binding的作用有一定认识:

本文章中的例子在这里可以看到。

时间: 2024-11-11 21:00:36

数据绑定(data binding )1的相关文章

Silverlight3系列(七)数据绑定 Data Binding 3 数据类型转换 Data Converte

Silverlight3系列(七)数据绑定 Data Binding 3 数据类型转换 Data Converter 7 数据转换 在普通的情况下,数据从后台到前台显示,没有任何变化.看起来是符合逻辑的,但是有可能不是你想要的效果,数据源的数据可能是的低级别的(这里的低级别是说数据比较原始,或者说是数据库可以理解的,不是最终用户可以理解的形式),你不想让他直接显示在界面上.例如:你可能会将数字变成用户可以看懂的形式.或者是想让日期显示成长格式的字符串.如果是这样的话,你需要将数据转换成正确的显示

Android简明开发教程十:数据绑定Data Binding

前面提到AndroidGraphics2DTutorial说过它是ListActivity派生出来的.ListActivity中显示的是ListView,ListView和 Gallery ,Spinner有一个共同点:它们都是AdapterView的子类.AdapterView的显示可以通过数据绑定来实现,数据源可以是 数组或是数据库记录,数据源和AdapterView是通过Adapter作为桥梁.通过Adapter,AdatperView可以显示数据源或处理用户选 取时间,如:选择列表中某项

Silverlight3系列(八)数据绑定 Data Binding 3 数据模板 Data Templates

8 数据模板 数据模板在xaml标记中是比较重要的,它定义了绑定对象如何显示.一共有两种类型的控件支持数据模板: 1)内容控件(具有Content属性的控件)通过ContentTemplate属性支持数据模板.用来显示你放在Content属性中的任何东西. 2)列表控件(从ItemsControl中继承而来的控件)通过ItemTemplate属性支持数据绑定.这个模板用来显示集合(你提供给ItemsSource属性的对象集合)中每一个Item. 列表模板是以内容模板为基础的,就好像ListBox

Silverlight3系列(四)数据绑定 Data Binding 1

今天我们讨论的是Silverlight3中的数据绑定,内容来自 <Pro Silverlight3 in C#>的读后感,中文名称可以译为<Silverlight3高级编程 C#版>.我找到的是一本PDF的,在网上可以搜索到下载地址. 数据绑定提供了一种,从对象中获取信息,然后显示在你的应用程序的界面上,同时不需要写冗长的代码就可以完成所有的工作的方式.通常情况下,富客户端提供两种绑定方式,不仅可以从兑现获取数据,显示到界面上,也可以将界面的数据传回给对象. Silverlight

Silverlight3系列(五)数据绑定 Data Binding 2

接着上面一篇,我们来讨论绑定集合等. 首先看一下可以进行绑定集合的控件属性,暂时我就不翻译了,因为翻译不好,还不如读英文呢. Name Description ItemsSource Points to the collection that has all the objects that will be shown in the list. DisplayMemberPath Identifies the property that will be used to creat the dis

数据绑定(data binding)3

数据绑定(Data Binding)-Part3 原文链接 : Data Binding – Part 3 原文作者 : Mark Allison 译文出自 : 开发技术前线 www.devtf.cn.未经允许,不得转载! 译者 : desmond1121 校对者: desmond1121 勘误:原文中使用ModelView一词,但实际上MVVM是Model-View-ViewModel,故应为ViewModel. 在之前的文章中,我们使用Data Binding与布局中的TextView配合搭

数据绑定(data binding)

据绑定(Data Binding)-Part2 原文链接 : Data Binding – Part 2 原文作者 : Mark Allison 译文出自 : 开发技术前线 www.devtf.cn.未经允许,不得转载! 译者 : desmond1121 校对者: desmond1121 在之前我们做了一个简单的Twitter客户端,但是简单地介绍ViewHolder实现,可能没有充分地让你明白Data Binding的使用方法.那么我们现在就来看看怎么样将Data Binding引入到项目中.

Android Data Binding数据绑定详解_Android

去年谷歌 I/O大会上介绍了一个非常厉害的新框架DataBinding, 数据绑定框架给我们带来了很大的方便,以前我们可能需要在每个Activity里写很多的findViewById,不仅麻烦,还增加了代码的耦合性,如果我们使用DataBinding,就可以抛弃那么多的findViewById,省时省力.说到这里,其实网上也有很多快速的注解框架,但是注解框架与DataBinding想比还是不好用,而且官网文档说DataBinding还能提高解析XML的速度,其实DataBinding的好用,不仅

数据绑定(data binding)2

据绑定(Data Binding)-Part2 原文链接 : Data Binding – Part 2 原文作者 : Mark Allison 译文出自 : 开发技术前线 www.devtf.cn.未经允许,不得转载! 译者 : desmond1121 校对者: desmond1121 在之前我们做了一个简单的Twitter客户端,但是简单地介绍ViewHolder实现,可能没有充分地让你明白Data Binding的使用方法.那么我们现在就来看看怎么样将Data Binding引入到项目中.