新聞中心
1 引入

如何高效地實(shí)現(xiàn)以下界面?
登錄/未登錄
有好幾年findViewById實(shí)戰(zhàn)經(jīng)驗(yàn)的我,感覺(jué)并不難啊。一般會(huì)
1.先定義一個(gè)User的Model類(lèi),數(shù)據(jù)來(lái)自JSON解析;
2.創(chuàng)建一個(gè)xml,隨后在xml中布局完所有View,對(duì)頭像、標(biāo)題、積分、登錄按鈕一個(gè)id;
3.在Activity中通過(guò)findViewById獲取到頭像ImageView、標(biāo)題TextView、積分TextView、登錄Button,然后給Button設(shè)置監(jiān)聽(tīng)器,再根據(jù)登陸狀態(tài)展示對(duì)應(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
你可能聽(tīng)說(shuō)過(guò)Jake Wharton的ButterKnife,這個(gè)庫(kù)只需要在定義View變量的時(shí)候通過(guò)注解傳入對(duì)應(yīng)id,隨后在onCreate時(shí)調(diào)用ButterKnife.bind(this)即可完成view的注入,示例如下:
2.2 Android Data Binding
如果使用了Android Data Binding,那么View的定義、find、判空這些都不用寫(xiě)了,如何做呢?
2.2.1 準(zhǔn)備工作
首先,你需要滿(mǎn)足一個(gè)條件:你的Android Plugin for Gradle版本必須等于或高于1.5.0-alpha1版本,這個(gè)版本位于根目錄build.gradle中,示例如下:
- buildscript {
- repositories {
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:2.1.0-rc1'
- }
- }
接著,你必須告訴編譯器開(kāi)啟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為例,原來(lái)的根節(jié)點(diǎn)為L(zhǎng)inearLayout,如下所示:
2.2.3 開(kāi)始享受樂(lè)趣吧!
在上述操作完成后,編譯器會(huì)自動(dòng)為我們生成
com.asha.demo.databinding.ActivityDetail2Binding.java類(lèi),這個(gè)類(lèi)的命令方式為:包名 + databinding + activity_detail2駝峰命名方式 + Binding.java。隨后,使用這個(gè)activity_detail2的DetailActivity2.java的代碼可以簡(jiǎn)化為:
- 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 等級(jí):%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、判空都不見(jiàn)了,所有的這些操作都在編譯器為我們生成的ActivityDetail2Binding.java中完成,只需要在onCreate時(shí)調(diào)用如下代碼進(jìn)行setContentView即可實(shí)現(xiàn),
binding = DataBindingUtil.setContentView(this,R.layout.activity_detail2);
我的天哪
2.2.4 ActivityDetail2Binding中注入View相關(guān)的代碼分析
可以在as中方便的查看編譯器自動(dòng)生成的類(lèi),這個(gè)類(lèi)位于/app/build/intermediates/classes/debug/com/asha/demo/databinding/ActivityDetail2Binding.class中,縮減掉Binding邏輯后的代碼為:
其中全局靜態(tài)SparseIntArray數(shù)組中存放了4個(gè)數(shù)字,這個(gè)四個(gè)數(shù)字為R.java中生成的對(duì)應(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)造的時(shí)候調(diào)用了mapBindings,一次解決了所有View的查找,mapBindings函數(shù)在ActvityDetail2Binding父類(lèi)ViewDataBinding中實(shí)現(xiàn)。
3 使用表達(dá)式在layout.xml中填充model數(shù)據(jù)
在ActivityDetail2.java中還存在大量的View控制、數(shù)據(jù)填充代碼,如何把這些代碼在交給layout.xml完成呢?
3.1 ModelAdapter類(lèi)
第2節(jié)中已經(jīng)定義了User.java類(lèi)作為Model類(lèi),但是我們經(jīng)常會(huì)遇到Model類(lèi)和真正View展示不一致的情況,本例子中定義一個(gè)來(lái)ModelAdapter類(lèi)來(lái)完整Model數(shù)據(jù)到展示數(shù)據(jù)的適配。示例代碼為ActivityDetail3.java的內(nèi)部類(lè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
網(wǎng)站欄目:【實(shí)戰(zhàn)】AndroidDataBinding從抵觸到愛(ài)不釋手
網(wǎng)站鏈接:http://www.dlmjj.cn/article/dhscodo.html


咨詢(xún)
建站咨詢(xún)
