今天要來聊聊關於ViewBinding的實作

以往我們以前在寫Android專案的時候,最基本的辣個語法

findViewById(R.id.view);

 

我想這句不管你是新手還是老手應該都很熟悉吧?無誤,這句話就是將介面xml元件連接Java控制文件的一個關鍵字

這個寫法的話,基本上整個介面只要有什麼元件就得至少寫個一行去串聯它

而如果介面有很多元件呢...那我也只能請你自求多福了(笑

 

也因此Google工程師們或許也想解決這個問題,所以在Android Jetpack套件組中就加入了今天我們要來談的ViewBinding功能

總之不廢話,先來看看實作吧

 

 

還有Github

->https://github.com/thumbb13555/AndroidBlogExamples/tree/main/DataBinding

 


 

1. 開啟DataBinding以及置換介面

 

首先打開build.gradle

 

build.gradle

plugins {
    id 'com.android.application'
}

android {
    namespace 'com.noahliu.databinding'
    compileSdk 33
    dataBinding{
        enabled = true
    }
    defaultConfig {
        applicationId "com.noahliu.databinding"
        minSdk 28
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

 

紅底白字的位置,將dataBinding設置為true

 

完成syne後,來到activity_main.xml,在介面上按住option+Enter (⌥+⮐),點擊這個

截圖 2023-06-10 上午10.17.33

 

這時候很聰明的介面就會幫你把介面置換成可以被viewBinding使用的介面囉!

好,這個段落先到這邊

接下來我們要來撰寫必要的檔案

 


 

2. 撰寫ViewBinding使用的實體類

 

首先請先在檔案中新增一個實體類

 

截圖 2023-06-10 下午3.15.33

 

再來在裡面撰寫如下

MyViewModel.java

package com.noahliu.databinding;

public class MyViewModel{
    public String multipliedBy11;
    public String multipliedBy21;
    public String multipliedBy31;
    public String multipliedBy41;
    public String multipliedBy51;

    public MyViewModel() {}
    public void setZero(){
        this.multipliedBy11 = null;
        this.multipliedBy21 = null;
        this.multipliedBy31 = null;
        this.multipliedBy41 = null;
        this.multipliedBy51 = null;
    }

    public void setMultipliedBy11(String multipliedBy11) {
        this.multipliedBy11 = multipliedBy11;
    }

    public void setMultipliedBy21(String multipliedBy21) {
        this.multipliedBy21 = multipliedBy21;
    }

    public void setMultipliedBy31(String multipliedBy31) {
        this.multipliedBy31 = multipliedBy31;
    }

    public void setMultipliedBy41(String multipliedBy41) {
        this.multipliedBy41 = multipliedBy41;
    }

    public void setMultipliedBy51(String multipliedBy51) {
        this.multipliedBy51 = multipliedBy51;
    }
}

 

OK,完成到這步驟後我們就可以開始對介面做一些手腳了

讓咱們回到activity_main.xml

然後直接給你所有程式

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="myText"
            type="String" />

        <variable
            name="myViewModel"
            type="com.noahliu.databinding.MyViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <EditText
            android:id="@+id/edBindExample"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="32dp"
            android:layout_marginEnd="32dp"
            android:hint="input"
            android:inputType="number"
            android:minHeight="48dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvOutput"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:text='@{myText,default="綁定變數測試"}'
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintEnd_toEndOf="parent"

            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/edBindExample" />

        <TextView
            android:id="@+id/tvMultipliedBy11"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:text='@{myViewModel.multipliedBy11 == null?"0*11=0":myViewModel.multipliedBy11,default="0*11=0"}'
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintBottom_toTopOf="@+id/tvMultipliedBy21"

            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <TextView
            android:id="@+id/tvMultipliedBy21"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:text='@{myViewModel.multipliedBy21 == null?"0*21=0":myViewModel.multipliedBy21,default="0*21=0"}'
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintBottom_toTopOf="@+id/tvMultipliedBy31"
            app:layout_constraintEnd_toEndOf="@+id/tvMultipliedBy11"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toStartOf="@+id/tvMultipliedBy11" />

        <TextView
            android:id="@+id/tvMultipliedBy31"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:text='@{myViewModel.multipliedBy31 == null?"0*31=0":myViewModel.multipliedBy31,default="0*31=0"}'
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintBottom_toTopOf="@+id/tvMultipliedBy41"
            app:layout_constraintEnd_toEndOf="@+id/tvMultipliedBy11"
            app:layout_constraintStart_toStartOf="@+id/tvMultipliedBy11" />

        <TextView
            android:id="@+id/tvMultipliedBy41"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:text='@{myViewModel.multipliedBy41 == null?"0*41=0":myViewModel.multipliedBy41,default="0*41=0"}'
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintBottom_toTopOf="@+id/tvMultipliedBy51"
            app:layout_constraintEnd_toEndOf="@+id/tvMultipliedBy11"
            app:layout_constraintStart_toStartOf="@+id/tvMultipliedBy11" />

        <TextView
            android:id="@+id/tvMultipliedBy51"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:text='@{myViewModel.multipliedBy51 == null?"0*51=0":myViewModel.multipliedBy51,default="0*51=0"}'
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintBottom_toTopOf="@+id/edBindExample"
            app:layout_constraintEnd_toEndOf="@+id/tvMultipliedBy11"
            app:layout_constraintStart_toStartOf="@+id/tvMultipliedBy11" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

在介面的部分,首先是這裡

截圖 2023-06-10 下午3.33.10

這個地方就是綁定資料的位置,通常一定要設置name與type

其實不用想太複雜,大致意義就是要你決定型別,例如String、Integer等等

當然也可以像下面的例子,將型別定為一個自定義的實體類

 

再來是橘底白字

截圖 2023-06-10 下午3.36.45

 

 

這裡就是將變數綁入到介面的設置,其中default則可以設置元件在沒有被設置的情況下預設顯示指定字串

再來是這裡

截圖 2023-06-10 下午3.42.49

 

注意,雖然這裡有自動換行,但是

這裡是不能換行的!!

這裡是不能換行的!!

這裡是不能換行的!!

 

這裡的換行是痞客邦的編輯器自動給我換的,如果在專案中這樣寫是會報錯的喔!

截圖 2023-06-10 下午3.45.58

 


 

3. 實際操作

 

直接上程式

MainActivity.java

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //mainBinding綁定給介面
        mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        mainBinding.setMyText("綁定變數測試");
        //也可以直接使用Binding來賦予點擊事件
        mainBinding.tvOutput.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "🦢🦢🦢🦢🦢", Toast.LENGTH_SHORT).show();
            }
        });
        mainBinding.edBindExample.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                MyViewModel values = new MyViewModel();
                if (editable.toString().equals("")){
                    values.setZero();
                    //可以使用viewBinding來賦值
                    mainBinding.setMyText("綁定變數測試");
                } else{
                    int num = Integer.parseInt(editable.toString());
                    int total = 0;
                    total += (num * 11)+(num * 21)+(num * 31)+(num * 41)+(num * 51);
                    values.setMultipliedBy11(editable.toString() + '*' + 11 + '=' + num * 11);
                    values.setMultipliedBy21(editable.toString() + '*' + 21 + '=' + num * 21);
                    values.setMultipliedBy31(editable.toString() + '*' + 31 + '=' + num * 31);
                    values.setMultipliedBy41(editable.toString() + '*' + 41 + '=' + num * 41);
                    values.setMultipliedBy51(editable.toString() + '*' + 51 + '=' + num * 51);
                    //當然,也可以普通地使用
                    mainBinding.tvOutput.setText("總和: "+total);
                }

                mainBinding.setMyViewModel(values);
            }
        });
    }
}

 

首先粉底白字的部分就是將介面綁入ViewBinding,算是最重要的一個部分

綁定完成後便可呼叫如同紫底白字部分所寫,使用它來控制介面參數囉

截圖 2023-06-10 下午4.03.33

 

最後在控制介面的部分在這邊,藍底白字部分供參考

截圖 2023-06-10 下午4.06.40

 


 

好的,做到這邊按下執行的話,想必應該是能如同我的範例一樣正常操作

其實這個在實際專案中,可能是因為還算比較新的框架,所以我也只有遇到過一次用ViewBinding的案子哈哈

而我今天提供的範例也只是這個功能中的最簡單的操作而已,實際上這功能真要搞的話花樣真的是比想像中的多很多XD

這部分就待日後我有想到的時候再來寫吧!

好的,最後..

TK2

arrow
arrow

    碼農日常 發表在 痞客邦 留言(3) 人氣()