Android Jetpack ViewBinding

ViewBinding(視圖綁定)
通過ViewBinding,可以更輕松地編寫可與視圖交互的代碼。在模塊中啟用ViewBinding后,系統(tǒng)會為該模塊中的每個XML布局文件生成一個綁定類袜硫。綁定類的實例包含對在相應(yīng)布局中具有ID的所有視圖的直接引用吹缔。多數(shù)情況下ViewBinding會替換掉findViewById。開啟方式有如下兩種方式:

    //方式一  
    viewBinding{
      enabled=true
    }
    //方式二 
    buildFeatures {
        viewBinding true
    }

如果希望在生成綁定類的時候忽略某個布局文件饺著,可以在布局文件的根目錄上添加tools:viewBindingIgnore="true"屬性。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:viewBindingIgnore="true">

</LinearLayout>

模塊開啟視圖綁定功能后,系統(tǒng)會為該模塊中包含的每個XML布局文件生成一個綁定類饵较。每個綁定類均包含對根View以及布局中具有ID的所有視圖的引用。系統(tǒng)生成綁定類的命名方式是:通過將XML文件的名稱去下劃線后轉(zhuǎn)換成駝峰式大小寫并在末尾添加"Binding"的方式遭赂。例如 activity_main.xml 會生成一個ActivityMainBinding的視圖綁定類循诉。如下為activity_main.xml文件的內(nèi)容

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/name_view"
        android:layout_width="match_parent"
        android:layout_height="46dp"
        android:gravity="center"
        android:text="@string/app_name" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="46dp"
        android:gravity="center"
        android:text="ceshi" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="46dp"
        android:text="確定" />
</LinearLayout>

此XML布局文件對應(yīng)的ActivityMainBinding類,包含了對根視圖的引用及具有ID 的View的引用撇他,通過綁定類 具體實例的getRoot()方法來獲取根視圖的引用茄猫,視圖中具有ID的view則會在綁定類中生成相應(yīng)ID名稱對應(yīng)的字段,如此視圖中的"name_view"和"button"這兩個view會在綁定類中生成nameView 和button兩個字段(字段生成規(guī)則為去下劃線后改駝峰式大小寫命名)困肩。具體生成的綁定類如下:

// Generated by view binder compiler. Do not edit!
package com.gexing.test.databinding;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewbinding.ViewBinding;
import com.gexing.test.R;
import java.lang.NullPointerException;
import java.lang.Override;
import java.lang.String;

public final class ActivityMainBinding implements ViewBinding {
  @NonNull
  private final LinearLayout rootView;

  @NonNull
  public final Button button;

  @NonNull
  public final TextView nameView;

  private ActivityMainBinding(@NonNull LinearLayout rootView, @NonNull Button button,
      @NonNull TextView nameView) {
    this.rootView = rootView;
    this.button = button;
    this.nameView = nameView;
  }

  @Override
  @NonNull
  public LinearLayout getRoot() {
    return rootView;
  }

  @NonNull
  public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater) {
    return inflate(inflater, null, false);
  }

  @NonNull
  public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup parent, boolean attachToParent) {
    View root = inflater.inflate(R.layout.activity_main, parent, false);
    if (attachToParent) {
      parent.addView(root);
    }
    return bind(root);
  }

  @NonNull
  public static ActivityMainBinding bind(@NonNull View rootView) {
    // The body of this method is generated in a way you would not otherwise write.
    // This is done to optimize the compiled bytecode for size and performance.
    int id;
    missingId: {
      id = R.id.button;
      Button button = rootView.findViewById(id);
      if (button == null) {
        break missingId;
      }

      id = R.id.name_view;
      TextView nameView = rootView.findViewById(id);
      if (nameView == null) {
        break missingId;
      }

      return new ActivityMainBinding((LinearLayout) rootView, button, nameView);
    }
    String missingId = rootView.getResources().getResourceName(id);
    throw new NullPointerException("Missing required view with ID: ".concat(missingId));
  }
}

ViewBinding如何在Activity和Fragment中使用:
上述綁定類中 我們發(fā)現(xiàn)有多個靜態(tài)類方法:

1.ActivityMainBinding inflate(@NonNull LayoutInflater inflater)
2.public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup parent, boolean attachToParent)
3.public static ActivityMainBinding bind(@NonNull View rootView)
這三個靜態(tài)方法的返回值都式綁定類類型的實例募疮,通過這個實例我們便可以獲取到相應(yīng)的rootView 由此便可以在activity和fragment中使用。

在Activity中使用:直接在onCreate方法中替換原有的setContentView(R.layout.activity_main)的方式

package com.gexing.test

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.gexing.test.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    lateinit var mainBinding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        setContentView(R.layout.activity_main)
        mainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mainBinding.root)
    }
}

在Fragment中使用:在onCreateView方法中處理

package com.gexing.test

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.gexing.test.databinding.ActivityMainBinding

class TestFragment : Fragment() {
    var mainBinding: ActivityMainBinding? = null
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mainBinding = mainBinding ?: ActivityMainBinding.inflate(inflater, container, false)
        return mainBinding?.root
    }
}
override fun onDestroyView() {
        super.onDestroyView()
        mainBinding = null
    }

ViewBinding與普通findViewById的區(qū)別:

1.Null安全僻弹,由于ViewBinding會創(chuàng)建對視圖的直接引用阿浓,因此不存在因視圖ID無效而引發(fā)的Null指針異常的風(fēng)險。此外如果視圖僅出現(xiàn)在布局的某些配置中蹋绽,則綁定類中包含其引用的字段會使用@Nullable標(biāo)記芭毙。
2.類型安全每個綁定類中的字段均具有與它們XML文件中引用的View相匹配的類型筋蓖,這意味著不存在類轉(zhuǎn)換異常的風(fēng)險。
這些差異意味著布局和代碼之間的不兼容將會導(dǎo)致構(gòu)建在編譯時失敗退敦,而非在運行時出現(xiàn)異常粘咖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市侈百,隨后出現(xiàn)的幾起案子瓮下,更是在濱河造成了極大的恐慌,老刑警劉巖钝域,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讽坏,死亡現(xiàn)場離奇詭異,居然都是意外死亡例证,警方通過查閱死者的電腦和手機(jī)路呜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來织咧,“玉大人胀葱,你說我怎么就攤上這事◇厦桑” “怎么了抵屿?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長捅位。 經(jīng)常有香客問我晌该,道長,這世上最難降的妖魔是什么绿渣? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任朝群,我火速辦了婚禮,結(jié)果婚禮上中符,老公的妹妹穿的比我還像新娘姜胖。我一直安慰自己,他們只是感情好淀散,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布右莱。 她就那樣靜靜地躺著,像睡著了一般档插。 火紅的嫁衣襯著肌膚如雪慢蜓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天郭膛,我揣著相機(jī)與錄音晨抡,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛耘柱,可吹牛的內(nèi)容都是我干的如捅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼调煎,長吁一口氣:“原來是場噩夢啊……” “哼镜遣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起士袄,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤悲关,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后娄柳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寓辱,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年西土,在試婚紗的時候發(fā)現(xiàn)自己被綠了讶舰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鞍盗。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡需了,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出般甲,到底是詐尸還是另有隱情肋乍,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布敷存,位于F島的核電站墓造,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锚烦。R本人自食惡果不足惜觅闽,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涮俄。 院中可真熱鬧蛉拙,春花似錦、人聲如沸彻亲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苞尝。三九已至畸肆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宙址,已是汗流浹背轴脐。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人豁辉。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓令野,卻偏偏與公主長得像,于是被迫代替她去往敵國和親徽级。 傳聞我的和親對象是個殘疾皇子气破,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

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