Skip to content

Commit 2ece2da

Browse files
committed
Data Binding Part5 翻译、校对完成。
1 parent 664e549 commit 2ece2da

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
#数据绑定(Data Binding)-Part5
2+
---
3+
4+
> * 原文链接 : [Data Binding - Part 5](https://blog.stylingandroid.com/data-binding-part-5/)
5+
* 原文作者 : [Mark Allison](https://blog.stylingandroid.com/)
6+
* 译文出自 : [开发技术前线 www.devtf.cn。未经允许,不得转载!](http://www.devtf.cn)
7+
* 译者 : [desmond1121](https://github.com/desmond1121)
8+
* 校对者: [desmond1121](https://github.com/desmond1121)
9+
10+
直到现在,我们已经见识到Data Binding的很多功能了。但是还有一个很强大的特点没有介绍,那就是观察者模式的应用。
11+
12+
观察者模式在数据会变化的时候非常有用。为了演示这个功能,我们假设Twiter API返回的`twitter4j.Status`中不会返回被转发的状态,并需要通过额外的网络请求来获取被转发的状态。并且在获取`twitter4j.Status`的同时去获取这条引用状态的话与之前的工作就没有区别了,我们要让用户在点击该条转发状态时,显示被转发的状态。之前已经展示过了怎么在Data Binding中使用点击响应,那么这次的工作就是在点击的时候获取被转发的状态,并更新UI。
13+
14+
应用观察者模式能够在数据更新的时候自动更新UI内容。每一个`Observable`是可以被许多个观察者(`Observer`)“观察”的,只要`Observable`的内容改变,它就会调用每一个观察者的回调函数,从而做出相应的应对。
15+
16+
我们可以让`Model`中的相关类变成`Observable`,或者也可以仅仅让类里面有可能发生改变的域变成`Observable`
17+
18+
现在扩展一下`Status`类:
19+
20+
public class Status {
21+
22+
private final String name;
23+
private final String screenName;
24+
private final String text;
25+
private final String imageUrl;
26+
private final Status quotedStatus;
27+
private ObservableField<Status> observableQuotedStatus;
28+
29+
public Status(@NonNull String name, @NonNull String screenName, @NonNull String text, @NonNull String imageUrl, @Nullable Status quotedStatus) {
30+
this.name = name;
31+
this.screenName = screenName;
32+
this.text = text;
33+
this.imageUrl = imageUrl;
34+
this.quotedStatus = quotedStatus;
35+
observableQuotedStatus = new ObservableField<>();
36+
}
37+
38+
public String getName() {
39+
return name;
40+
}
41+
42+
public String getScreenName() {
43+
return screenName;
44+
}
45+
46+
public String getText() {
47+
return text;
48+
}
49+
50+
public String getImageUrl() {
51+
return imageUrl;
52+
}
53+
54+
public boolean hasQuotedStatus() {
55+
return quotedStatus != null;
56+
}
57+
58+
public void updateQuotedStatus() {
59+
observableQuotedStatus.set(quotedStatus);
60+
}
61+
62+
public void clearQuotedStatus() {
63+
observableQuotedStatus.set(null);
64+
}
65+
66+
public ObservableField<Status> getObservableQuotedStatus() {
67+
return observableQuotedStatus;
68+
}
69+
}
70+
71+
72+
之前我们已经在Status里面加入了被转发的状态对象,它会在存在的时候显示到界面上。而这一次,我们没有把它直接暴露给外部,而是将其包装在了`ObservableFiled`中,通过`updateQuotedStatus()`来获得。
73+
74+
我们将在点击事件中将`Observable`在set与null状态之间转换。如果这部分需要进行网络请求,你可以在开始网络请求的时候更新UI至一个等待状态,在网络请求返回的时候再更新UI。
75+
76+
public class ClickHandler {
77+
private final Status status;
78+
79+
public ClickHandler(Status status) {
80+
this.status = status;
81+
}
82+
83+
public void onClick(View view) {
84+
if (status.getObservableQuotedStatus().get() == null) {
85+
status.updateQuotedStatus();
86+
} else {
87+
status.clearQuotedStatus();
88+
}
89+
}
90+
}
91+
92+
93+
最后我们需要为转发布局绑定变量。它和之前的布局代码十分相似,区别只不过绑定的对象是`Observable`而已。并且它会根据`Observable`变量是否为null值来判断是否要显示在屏幕上。
94+
95+
<?xml version="1.0" encoding="utf-8"?>
96+
<layout xmlns:android="http://schemas.android.com/apk/res/android"
97+
xmlns:app="http://schemas.android.com/apk/res-auto">
98+
99+
<data>
100+
101+
<import type="android.view.View" />
102+
103+
<variable
104+
name="status"
105+
type="com.stylingandroid.databinding.data.Status" />
106+
107+
<variable
108+
name="handler"
109+
type="com.stylingandroid.databinding.ClickHandler" />
110+
111+
</data>
112+
113+
<RelativeLayout
114+
android:id="@+id/status_container"
115+
android:layout_width="match_parent"
116+
android:layout_height="match_parent">
117+
.
118+
.
119+
.
120+
<RelativeLayout
121+
android:id="@+id/status_quoted"
122+
android:layout_width="match_parent"
123+
android:layout_height="wrap_content"
124+
android:layout_alignLeft="@id/status_text"
125+
android:layout_alignStart="@id/status_text"
126+
android:layout_below="@id/status_text"
127+
android:layout_marginTop="8dp"
128+
android:background="@color/light_grey"
129+
android:onClick="@{handler.onClick}"
130+
android:padding="8dp"
131+
android:visibility="@{status.hasQuotedStatus ? View.VISIBLE : View.GONE}">
132+
133+
<TextView
134+
android:id="@+id/quoted_tap"
135+
style="@style/Status.Name"
136+
android:layout_width="wrap_content"
137+
android:layout_height="wrap_content"
138+
android:layout_alignParentLeft="true"
139+
android:layout_alignParentStart="true"
140+
android:layout_alignParentTop="true"
141+
android:text="@string/tap_to_load"
142+
android:visibility="@{status.observableQuotedStatus == null ? View.VISIBLE : View.GONE}" />
143+
144+
<ImageView
145+
android:id="@+id/quoted_status_avatar"
146+
android:layout_width="64dp"
147+
android:layout_height="64dp"
148+
android:layout_alignParentLeft="true"
149+
android:layout_alignParentStart="true"
150+
android:layout_alignParentTop="true"
151+
android:contentDescription="@null"
152+
android:visibility="@{status.observableQuotedStatus == null ? View.GONE : View.VISIBLE}"
153+
app:imageUrl="@{status.observableQuotedStatus.imageUrl}" />
154+
155+
<TextView
156+
android:id="@+id/quoted_status_name"
157+
style="@style/Status.Name"
158+
android:layout_width="wrap_content"
159+
android:layout_height="wrap_content"
160+
android:layout_alignParentTop="true"
161+
android:layout_marginLeft="8dp"
162+
android:layout_marginStart="8dp"
163+
android:layout_toEndOf="@id/quoted_status_avatar"
164+
android:layout_toRightOf="@id/quoted_status_avatar"
165+
android:text="@{status.observableQuotedStatus.name}"
166+
android:visibility="@{status.observableQuotedStatus == null ? View.GONE : View.VISIBLE}" />
167+
168+
<TextView
169+
android:id="@+id/quoted_status_screen_name"
170+
style="@style/Status.ScreenName"
171+
android:layout_width="wrap_content"
172+
android:layout_height="wrap_content"
173+
android:layout_alignBaseline="@id/quoted_status_name"
174+
android:layout_marginLeft="4dip"
175+
android:layout_marginStart="4dip"
176+
android:layout_toEndOf="@id/quoted_status_name"
177+
android:layout_toRightOf="@id/quoted_status_name"
178+
android:text="@{&quot;@&quot; + status.observableQuotedStatus.screenName}"
179+
android:visibility="@{status.observableQuotedStatus == null ? View.GONE : View.VISIBLE}" />
180+
181+
<TextView
182+
android:id="@+id/quoted_status_text"
183+
style="@style/Status.Text"
184+
android:layout_width="wrap_content"
185+
android:layout_height="wrap_content"
186+
android:layout_alignLeft="@id/quoted_status_name"
187+
android:layout_alignStart="@id/quoted_status_name"
188+
android:layout_below="@id/quoted_status_name"
189+
android:singleLine="false"
190+
android:text="@{status.observableQuotedStatus.text}"
191+
android:visibility="@{status.observableQuotedStatus == null ? View.GONE : View.VISIBLE}" />
192+
</RelativeLayout>
193+
194+
</RelativeLayout>
195+
</layout>
196+
197+
198+
这样就做好了全部工作,UI界面会在网络请求返回的时候自动更新!以下是Demo视频链接:
199+
200+
[Demo视频链接 From Youtube](https://youtu.be/LXXyFqJ8owo)
201+
202+
[Demo视频链接 From Youku](http://v.youku.com/v_show/id_XMTM2MzMwNzU0OA==.html)
203+
204+
至此我们就将Data Binding库的基本功能都介绍完毕了。我要承认,一开始我对Data Binding的使用是持怀疑态度的,因为它让我联想到了JSP。所以我并不支持大家在layout布局文件中加入太多代码逻辑。但是在使用了这个库之后,我发现它太强大了,在布局文件中嵌入代码逻辑的好处也是显而易见的。当它结束测试正式发布之后,我一定会考虑将其应用到商业工程中!
205+
206+
本文中的例子在[这里](https://github.com/StylingAndroid/DataBinding/tree/Part5)可以看到。

0 commit comments

Comments
 (0)