title: 翻譯:no more findViewById
date: 2016-06-26 14:40:57
tags:
- android
- 翻譯
- 原文鏈接 https://medium.com/google-developers/no-more-findviewbyid-457457644885#.cs0jg2og6
- 翻譯: Adamin90
- 轉(zhuǎn)載請注明出處漾岳,謝謝!
No More findViewById
Android Studio開發(fā)android程序的一個小特點(diǎn)是數(shù)據(jù)綁定。我會在將來的文章中講解它的其他一些優(yōu)雅的特點(diǎn),但是你要了解的最基礎(chǔ)的是怎樣消除findViewById.
TextView hello = (TextView) findViewById(R.id.hello);
雖然現(xiàn)在有很多試用的方法可以省略這些多余代碼,但是Android Studio 1.5以及更高版本已經(jīng)有官方的方法了侧戴。
首先,你必須在Application的build.gradle里的android塊內(nèi)填寫如下代碼:
android {
…
dataBinding.enabled = true
}
下一步就是在你的layout文件的最外層添加 <layout>標(biāo)簽跌宛,不管你用的是任何 ViewGroup:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
</layout>
Layout標(biāo)簽告訴Android Studio這個layout在編譯時將進(jìn)行額外的操作酗宋,查找到所有感興趣的view,并且標(biāo)簽為下一步。所有外部沒有包layout
標(biāo)簽的布局將不會執(zhí)行額外操作疆拘。所以你可以在新項目中少量使用而無需改變項目中其他的部分蜕猫。
下面要做的就是告訴它在運(yùn)行時分別加載你的layout。因為它向后兼容哎迄,所以不需要依賴新框架的改變來加載這些預(yù)執(zhí)行的layout文件回右。因此你只需對程序做一個輕微的改變。
從一個Activity,不是:
{% codeblock lang:java %}
setContentView(R.layout.hello_world);
TextView hello = (TextView) findViewById(R.id.hello);
hello.setText("Hello World");
{% endcodeblock %}
而是這樣加載:
HelloWorldBinding binding =
DataBindingUtil.setContentView(this, R.layout.hello_world);
binding.hello.setText("Hello World");
你可以看到 HelloWordBinding這個類自動為hello_world.xml生成并且id為“@+id/hello”的view分配到了一個hello的field你可以使用漱挚。沒有強(qiáng)制類型轉(zhuǎn)換翔烁,沒有findViewById.
這標(biāo)兵這是訪問view的機(jī)制不僅僅比findViewById更加簡單,而且也更加快旨涝!綁定程序一次執(zhí)行覆蓋所有l(wèi)ayout的view蹬屹,把view分配到field。當(dāng)你運(yùn)行findViewById,的時候view結(jié)構(gòu)每次都會被遍歷查找慨默。
你會注意到一件事:它對你的變量名使用了駝峰命名法(比如hello_world.html 變成類 HelloWorldBinding),所以如果你給它的id是“@+id/hello_text”,那么field的名稱將會是 helloText.
當(dāng)你正在inflate你布局里RecyclerView,ViewPager贩耐,或其他不設(shè)置Activity內(nèi)容的控件,你將希望在生成的類上用生成的類型安全的方法厦取,這里有幾個版本匹配LayoutInflater,所以使用你最適合食用的.舉個例子:
HelloWorldBinding binding = HelloWorldBinding.inflate(
getLayoutInflater(), container, attachToContainer);
如果你們有把被inflate的view 附加到包含他們的ViewGroup上潮太,你必須訪問被infalte的view的view結(jié)構(gòu)。你可以用binding的getRoot()方法:
linearLayout.addView(binding.getRoot());
現(xiàn)在蒜胖,你可能會考慮消别,如果我有一個layout包含同步view的不同配置呢?layout預(yù)執(zhí)行和運(yùn)行時inflate階段通過添加所有View 的id到生成的類台谢,如果沒有被inflate的話設(shè)置為null寻狂。
相當(dāng)神奇,不是嗎朋沮?最好的部分是運(yùn)行時沒有反射和其他任何高消耗的技術(shù)蛇券。把他少量添加到你現(xiàn)有程序里面非常容易,他能讓你的生活更加簡單樊拓,讓你的layout加載的更快纠亚!