Android View Binding使用詳解

View Binding(視圖綁定)

視圖綁定是一項(xiàng)功能卒暂,可讓你更輕松地編寫與視圖交互的代碼。在模塊中啟用視圖綁定后撞叽,它會為該模塊中存在的每個 XML 布局文件生成一個 綁定類姻成。綁定類的實(shí)例包含對在相應(yīng)布局中具有 ID 的所有視圖的直接引用。

在大多數(shù)情況下愿棋,View Binding會替換findViewById.

設(shè)置

視圖綁定在一個模塊一個模塊的基礎(chǔ)上啟用科展。要在模塊中啟用視圖綁定,請?jiān)?strong>Module級build.gradle文件中將viewBinding構(gòu)建選項(xiàng)設(shè)置為true糠雨,如下例所示:

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

如果你那個布局文件不需要生成綁定類(不想用這個功能)才睹,請將該 tools:viewBindingIgnore="true" 屬性添加到該布局文件的根視圖中:

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

使用

如果為Module啟用了視圖綁定,則會為Module包含的每個 XML 布局文件生成一個綁定類每個綁定類都包含對根視圖和所有具有 ID 的視圖引用琅攘。綁定類的名稱是通過將 XML 文件的名稱轉(zhuǎn)換為 Pascal 大小寫并在末尾添加Binding一詞來生成的垮庐。

例如,給定一個名為activity_progressbar.xml的布局文件:

<LinearLayout>
...
    <ProgressBar
        android:id="@+id/progress_1"/>
<ProgressBar
    style="@android:style/Widget.ProgressBar.Small" />
    <ProgressBar
        android:id="@+id/progress_3"/>
    <ProgressBar
        style="@android:style/Widget.ProgressBar.Inverse" />
    <ProgressBar
        android:id="@+id/progress_5"/>
    <ProgressBar
        style="@android:style/Widget.ProgressBar.Large.Inverse" />
...
</LinearLayout>

布局文件中有6個ProgressBar坞琴,只有3個ProgressBar設(shè)置了android:id哨查。

生成的綁定類稱為ActivityProgressbarBinding。這個類有3個字段:progress_1剧辐、progress_3寒亥、progress_5。另外3個在布局具有沒有ID荧关,所以在綁定類沒有提及溉奕。

每個綁定類還包含一個getRoot()方法,為相應(yīng)布局文件的根視圖提供直接引用忍啤。在這個例子中加勤,類中的getRoot()方法ActivityProgressbarBinding返回 LinearLayout根視圖。

在Activity中使用視圖綁定

要設(shè)置用于Activity的綁定類的實(shí)例同波,請?jiān)贏ctivity的onCreate()方法中執(zhí)行以下步驟 :

  • 1.調(diào)用inflate()包含在生成的綁定類中的靜態(tài)方法胸竞。這會為要使用的活動創(chuàng)建綁定類的實(shí)例。
  • 2.通過調(diào)用getRoot()方法獲取對根視圖的引用参萄。
  • 3.將根視圖傳遞給以 setContentView() 使其成為屏幕上的活動視圖卫枝。

實(shí)例如下:

private ActivityProgressbarBinding activityProgressbarBinding;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityProgressbarBinding = ActivityProgressbarBinding.inflate(getLayoutInflater());
//        View view = activityProgressbarBinding.getRoot();
//        setContentView(view);
        //一步到位也可以
        setContentView(activityProgressbarBinding.getRoot());
        
        //使用綁定類的實(shí)例來引用任何View(XML中必須添加id)
        activityProgressbarBinding.progress1.setMax(120);
        activityProgressbarBinding.progress3.setProgress(20);
    }

在Fragment中使用視圖綁定

要設(shè)置與Fragment一起使用的綁定類的實(shí)例,請?jiān)贔ragment的onCreateView()方法中執(zhí)行以下步驟 :

  • 1.調(diào)用inflate()包含在生成的綁定類中的靜態(tài)方法讹挎。這會為要使用的Fragment創(chuàng)建綁定類的實(shí)例校赤。
  • 2.通過調(diào)用getRoot()方法獲取對根視圖的引用。
  • 3.從onCreateView()方法返回根視圖筒溃,使其成為屏幕上的活動視圖马篮。

注意: 該inflate()方法要求你傳入布局充氣器。如果布局已經(jīng)inflated怜奖,你可以改為調(diào)用綁定類的靜態(tài)bind()方法浑测。

實(shí)例如下:

private FragmentMineBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    binding = FragmentMineBinding.inflate(inflater,container,false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroy() {
    super.onDestroy();
    binding = null;
}

提供不同配置的提示

當(dāng)你跨多個配置聲明視圖時(shí),有時(shí)根據(jù)特定布局使用不同的視圖類型是有意義的歪玲。例如:

# in res/layout/example.xml
<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" />

在這種情況下迁央,你可能希望生成的類公開一個userBio type字段TextView,因?yàn)門extView是公共基類滥崩。不幸的是岖圈,由于技術(shù)限制,視圖綁定代碼生成器無法做出這個決定钙皮,View而是簡單地生成一個字段蜂科。這將需要稍后使用binding.userBio as TextView.

為了解決這個限制顽决,視圖綁定支持一個tools:viewBindingType 屬性,允許你告訴編譯器在生成的代碼中使用什么類型导匣。在上面的示例中才菠,你可以使用此屬性使編譯器將字段生成為TextView:

# in res/layout/example.xml (unchanged)
<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />

在另一個示例中,假設(shè)你有兩個布局贡定,其中一個包含 BottomNavigationView赋访,另一個包含 NavigationRailView。這兩個類NavigationBarView都包含了大部分實(shí)現(xiàn)細(xì)節(jié)厕氨。如果你的代碼不需要確切知道當(dāng)前布局中存在哪個子類进每,你可以使用tools:viewBindingType將生成的類型設(shè)置為NavigationBarView在兩個布局中:

# in res/layout/navigation_example.xml
<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

# in res/layout-w720/navigation_example.xml
<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

注意: 視圖綁定在生成代碼時(shí)無法驗(yàn)證此屬性的值汹粤。為避免編譯時(shí)和運(yùn)行時(shí)錯誤命斧,該值必須滿足以下條件:

  • 該值必須是繼承自android.view.View的類。
  • 該值必須是放置它的標(biāo)簽的超類嘱兼。例如国葬,以下值將不起作用:
<!-- ImageView is not related to TextView --> 
<TextView tools:viewBindingType="ImageView" /> 

<!-- Button is not a superclass of TextView -->
<TextView tools:viewBindingType="Button" /> 
  • 最終類型必須在所有配置中一致解析。

與 findViewById 的區(qū)別

與使用相比芹壕,View binding具有重要的優(yōu)勢findViewById:

  • 空安全:由于視圖綁定創(chuàng)建了對視圖的直接引用汇四,因此不存在因視圖 ID 無效而導(dǎo)致空指針異常的風(fēng)險(xiǎn)。此外踢涌,當(dāng)視圖僅存在于布局的某些配置中時(shí)通孽,綁定類中包含其引用的字段會標(biāo)記為 @Nullable。
  • 類型安全:每個綁定類中的字段的類型與其在 XML 文件中引用的視圖相匹配睁壁。這意味著沒有類轉(zhuǎn)換異常的風(fēng)險(xiǎn)背苦。

這些差異意味著你的布局和代碼之間的不兼容性將導(dǎo)致你的構(gòu)建在編譯時(shí)而不是運(yùn)行時(shí)失敗。

與數(shù)據(jù)綁定的比較

View binding和Data Binding都生成可用于直接引用視圖的綁定類潘明。但是行剂,View binding旨在處理更簡單的用例,并提供以下優(yōu)于Data Binding的好處:

  • 更快的編譯: 視圖綁定不需要注釋處理钳降,因此編譯時(shí)間更快厚宰。
  • 易用性: 視圖綁定不需要特別標(biāo)記的 XML 布局文件,因此在您的應(yīng)用程序中采用它的速度更快遂填。在模塊中啟用視圖綁定后铲觉,它會自動應(yīng)用于該模塊的所有布局。

相反吓坚,與數(shù)據(jù)綁定相比备燃,視圖綁定有以下限制:

  • 視圖綁定不支持布局變量或布局表達(dá)式,因此它不能用于直接從 XML 布局文件聲明動態(tài) UI 內(nèi)容凌唬。

布局變量或布局表達(dá)式: 表達(dá)式語言允許您編寫處理由視圖調(diào)度的事件的表達(dá)式并齐。數(shù)據(jù)綁定庫會自動生成將布局中的視圖與數(shù)據(jù)對象綁定所需的類漏麦。

  • 視圖綁定不支持雙向數(shù)據(jù)綁定。

雙向數(shù)據(jù)綁定: 單向數(shù)據(jù)綁定况褪,你可以在屬性上設(shè)置一個值并設(shè)置一個對該屬性更改做出反應(yīng)的listener撕贞,雙向數(shù)據(jù)綁定提供了此過程的快捷方式。

由于這些考慮测垛,在某些情況下最好在項(xiàng)目中同時(shí)使用View Binding和Data Binding捏膨。你可以在需要高級功能的布局中使用Data Binding,而在不需要高級功能的布局中使用View Binding食侮。

注意: 在很多情況下号涯,視圖綁定可以提供與數(shù)據(jù)綁定相同的好處,但實(shí)現(xiàn)更簡單锯七,性能更好链快。如果您主要使用數(shù)據(jù)綁定來替換findViewById() 調(diào)用,使用視圖綁定更佳眉尸。

以上就是View Binding(視圖綁定)的全部內(nèi)容域蜗,希望對你有所幫助。以后有條件了咱們再學(xué)習(xí)一下了Data Binding(數(shù)據(jù)綁定)噪猾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霉祸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子袱蜡,更是在濱河造成了極大的恐慌丝蹭,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坪蚁,死亡現(xiàn)場離奇詭異奔穿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)迅细,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門巫橄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茵典,你說我怎么就攤上這事湘换。” “怎么了统阿?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵彩倚,是天一觀的道長。 經(jīng)常有香客問我扶平,道長帆离,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任结澄,我火速辦了婚禮哥谷,結(jié)果婚禮上岸夯,老公的妹妹穿的比我還像新娘。我一直安慰自己们妥,他們只是感情好猜扮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著监婶,像睡著了一般旅赢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惑惶,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天煮盼,我揣著相機(jī)與錄音,去河邊找鬼带污。 笑死僵控,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的刮刑。 我是一名探鬼主播喉祭,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼养渴,長吁一口氣:“原來是場噩夢啊……” “哼雷绢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起理卑,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤翘紊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后藐唠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帆疟,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年宇立,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了踪宠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡妈嘹,死狀恐怖柳琢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情润脸,我是刑警寧澤柬脸,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站毙驯,受9級特大地震影響倒堕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜爆价,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一垦巴、第九天 我趴在偏房一處隱蔽的房頂上張望媳搪。 院中可真熱鬧,春花似錦骤宣、人聲如沸蛾号。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲜结。三九已至,卻和暖如春活逆,著一層夾襖步出監(jiān)牢的瞬間精刷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工蔗候, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怒允,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓锈遥,卻偏偏與公主長得像纫事,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子所灸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容