新聞中心
1 引入

如何高效地實(shí)現(xiàn)以下界面?
登錄/未登錄
有好幾年findViewById實(shí)戰(zhàn)經(jīng)驗(yàn)的我,感覺并不難啊。一般會
1.先定義一個User的Model類,數(shù)據(jù)來自JSON解析;
2.創(chuàng)建一個xml,隨后在xml中布局完所有View,對頭像、標(biāo)題、積分、登錄按鈕一個id;
3.在Activity中通過findViewById獲取到頭像ImageView、標(biāo)題TextView、積分TextView、登錄Button,然后給Button設(shè)置監(jiān)聽器,再根據(jù)登陸狀態(tài)展示對應(yīng)數(shù)據(jù);
實(shí)現(xiàn)如下:
- User.java
- activity_detail.xml
- DetailActivity
2 去掉煩人的findViewById(View注入)
可以看到,在Activity中View的定義、find、判空占據(jù)了大量篇幅,我們需要更優(yōu)雅的實(shí)現(xiàn)。
2.1 ButterKnife
你可能聽說過Jake Wharton的ButterKnife,這個庫只需要在定義View變量的時候通過注解傳入對應(yīng)id,隨后在onCreate時調(diào)用ButterKnife.bind(this)即可完成view的注入,示例如下:
2.2 Android Data Binding
如果使用了Android Data Binding,那么View的定義、find、判空這些都不用寫了,如何做呢?
2.2.1 準(zhǔn)備工作
首先,你需要滿足一個條件:你的Android Plugin for Gradle版本必須等于或高于1.5.0-alpha1版本,這個版本位于根目錄build.gradle中,示例如下:
- buildscript {
- repositories {
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:2.1.0-rc1'
- }
- }
接著,你必須告訴編譯器開啟Data Binding,一般位于app:build.gradle的android標(biāo)簽中,示例如下:
- android {
- compileSdkVersion 23
- buildToolsVersion "23.0.2"
- dataBinding {
- enabled true
- }
- ...
- }
2.2.2 修改layout.xml
以activity_detail.xml為例,原來的根節(jié)點(diǎn)為LinearLayout,如下所示:
2.2.3 開始享受樂趣吧!
在上述操作完成后,編譯器會自動為我們生成
com.asha.demo.databinding.ActivityDetail2Binding.java類,這個類的命令方式為:包名 + databinding + activity_detail2駝峰命名方式 + Binding.java。隨后,使用這個activity_detail2的DetailActivity2.java的代碼可以簡化為:
- public class DetailActivity2 extends AppCompatActivity {
- ActivityDetail2Binding binding; @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState);
- binding = DataBindingUtil.setContentView(this,R.layout.activity_detail2);
- login();
- } private void login(){ fill(User.newInstance()); } private void logout(){ fill(null); } private void fill(final User user){ final int visibility = user != null ? View.VISIBLE : View.GONE; if (user != null){
- binding.detailAvatar.setImageDrawable(ContextCompat.getDrawable(this,user.getAvatar()));
- binding.detailName.setText(user.getName());
- binding.detailDesc.setText(String.format("積分:%d 等級:%d",user.getScore(),user.getLevel()));
- }
- binding.detailAvatar.setVisibility(visibility);
- binding.detailName.setVisibility(visibility);
- binding.detailDesc.setVisibility(visibility);
- binding.detailActionButton.setOnClickListener(new View.OnClickListener() { @Override
- public void onClick(View v) { if (user == null) login(); else logout();
- }
- });
- binding.detailActionButton.setText(user == null ? "登錄":"退出登錄");
- }
- }
是的,所有View的定義、find、判空都不見了,所有的這些操作都在編譯器為我們生成的ActivityDetail2Binding.java中完成,只需要在onCreate時調(diào)用如下代碼進(jìn)行setContentView即可實(shí)現(xiàn),
binding = DataBindingUtil.setContentView(this,R.layout.activity_detail2);
我的天哪
2.2.4 ActivityDetail2Binding中注入View相關(guān)的代碼分析
可以在as中方便的查看編譯器自動生成的類,這個類位于/app/build/intermediates/classes/debug/com/asha/demo/databinding/ActivityDetail2Binding.class中,縮減掉Binding邏輯后的代碼為:
其中全局靜態(tài)SparseIntArray數(shù)組中存放了4個數(shù)字,這個四個數(shù)字為R.java中生成的對應(yīng)View的id,
- public final class R {
- ... public static final class id {
- ... public static final int detail_action_button = 2131492951; public static final int detail_avatar = 2131492948; public static final int detail_desc = 2131492950; public static final int detail_name = 2131492949;
- ...
- }
- ...
- }
在ActvityDetail2Binding實(shí)例構(gòu)造的時候調(diào)用了mapBindings,一次解決了所有View的查找,mapBindings函數(shù)在ActvityDetail2Binding父類ViewDataBinding中實(shí)現(xiàn)。
3 使用表達(dá)式在layout.xml中填充model數(shù)據(jù)
在ActivityDetail2.java中還存在大量的View控制、數(shù)據(jù)填充代碼,如何把這些代碼在交給layout.xml完成呢?
3.1 ModelAdapter類
第2節(jié)中已經(jīng)定義了User.java類作為Model類,但是我們經(jīng)常會遇到Model類和真正View展示不一致的情況,本例子中定義一個來ModelAdapter類來完整Model數(shù)據(jù)到展示數(shù)據(jù)的適配。示例代碼為ActivityDetail3.java的內(nèi)部類,可以調(diào)用ActivityDetail3.java中的函數(shù),代碼定義如下:
3.2 activity_detail3.xml中使用model
同樣復(fù)制一份activity_detail2.xml為activity_detail3.xml,在
隨后,就可以在下面的view中使用表達(dá)式了,全部布局文件如下:
- android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent">
- android:background="@color/detail_background"
- android:layout_width="match_parent"
- android:layout_height="66dp">
- android:src="@{adapter.avatar}"
- android:visibility="@{visibility}"
- android:id="@+id/detail_avatar"
- android:layout_gravity="center"
- android:layout_marginTop="-33dp"
- android:layout_width="66dp"
- android:layout_height="66dp" />
- android:visibility="@{visibility}"
- android:text="@{adapter.name}"
- android:id="@+id/detail_name"
- android:textSize="17sp"
- android:textColor="@color/textColorPrimary"
- android:layout_marginTop="15dp"
- android:layout_gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- android:visibility="@{visibility}"
- android:text="@{adapter.desc}"
- android:id="@+id/detail_desc"
- android:layout_marginTop="15dp"
- android:textSize="13sp"
- android:layout_gravity="center"%3
分享標(biāo)題:【實(shí)戰(zhàn)】AndroidDataBinding從抵觸到愛不釋手
鏈接URL:http://m.fisionsoft.com.cn/article/dhscodo.html


咨詢
建站咨詢
