Day24 Android - databinding(单向绑定)

databinding可用於将class的data与元件绑定,像是(findViewById、onClickListener)等UI绑定、监听的代码都可以用databinding来实现,在程序设计的越来越大时,算是相当好用的一个应用,那麽就开始今天的主题。

依赖

首先在gradle/android加入:

android {
    ...
    dataBinding {
        enabled = true
    }
}

等Sync now完之後就可以来更改布局。


布局

https://ithelp.ithome.com.tw/upload/images/20210907/20139259y61b63HV0I.png
在最外层的布局中按alt+enter就会跑出这样的画面,然後点选Convert to data binding layout,他就会帮你设计成包data的格式。

<?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>
        <!--写viewmodel-->
    </data>

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

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

那麽等等再回来改布局的部分,接着先建一个Model的class,我设计的model带有两个栏位(name、phone)。

public class Model {
    private String name;
    private String phone;
    public Model(String name, String phone){
        this.name=name;
        this.phone=phone;
    }
    public String getName() {
        return "你的名字是:"+name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return "你的电话是:"+phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
    //button的onclick方法,谈布局时会再提
    public void click(View view){
        Toast.makeText(view.getContext(),"SEND",Toast.LENGTH_SHORT).show();
    }
}

因为是单向绑定,所以我们没办法透过绑定edittext来使用其输入,但我们可以透过回到MainActivity来设计,首先先到布局调整资料。

<?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="Model"
            type="com.example.databinding.Model" />
    </data>
    
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/textview"
            android:layout_width="178dp"
            android:layout_height="44dp"
            android:gravity="left"
            android:text="@{Model.name}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHorizontal_bias="0.536"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.263" />

        <TextView
            android:id="@+id/textview2"
            android:layout_width="178dp"
            android:layout_height="44dp"
            android:gravity="left"
            android:text="@{Model.phone}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHorizontal_bias="0.536"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.391" />

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="236dp"
            android:text="Button"
            android:onClick="@{Model::click}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent" />

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

绑定的方法就是用自己variable设的name,另外透过getter来取得资料,像是@{Model.name}也就是从model里面的getName方法来取得name值。
按钮的话分很多种写法,假设variable name是Model、而click是方法名,就像是:

android:onClick="@{Model.click}"
android:onClick="@{Model::click}"
android:onClick="@{{(view)->model.click(obj data(传入资料),view(传入view))}}"

大概还蛮多种的,但目前我比较常写到的是这三种,按钮都可以用这些方法来做监听的动作,但都需要在你对应variable的type里面宣告这个方法名。

public void click(View view){
//要做的事
}
//第三种(传入资料、view)
public void click(obj data,View view){
//要做的事
}

大约是这样,那麽接着看到MainActivity来input资料。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        //ActivityMainBinding需先build(ctrl+f9)才会建立,使用Databinding的setContentView方法
        ActivityMainBinding binding = DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
        //建立data资料
        Model data = new Model("Android","0800-000-000");
        //设定资料
        binding.setModel(data);
    }
}

这样就完成了简易的databinding单向绑定,而双向绑定则需要将model定义成ObservableField(如下)

public ObservableField<String> name = new ObservableField<>();
public ObservableField<String> phone = new ObservableField<>();

而布局元件的绑定要多加"=",对edittext也绑定时,就能在edittext输入值时,textview跟着显示。
(以name来说,若以改为上面的ObservableField型态,在对应的元件都加入text属性的绑定)

<!--edittext-->
android:text="@={Model.name}"
<!--textview-->
android:text="@={Model.name}"

这样就算是简单的双向绑定了,另外其他更广的应用可能就得使用@Bindable、@BindingAdapter或@InverseBindingAdapter。

成果

https://ithelp.ithome.com.tw/upload/images/20210909/20139259BmAKF3BESZ.jpg


<<:  [Day-30] 最後一天的小练习

>>:  Day25|【Git】git stash 暂存档案

[Day12] CH08:积沙成塔——Array & ArrayList(中)

还记得我们前两天学的方法吗?结合昨天学的阵列,阵列也可以用在方法里传递吗? 当然可以罗!我们就先来看...

Day3 逻辑斯回归(Logistic Regression)

逻辑斯回归是什麽? 讲人话就是一种对数机率模型,主要用来处理二元[非此即彼(Yes or No)]分...

[DAY 07]环境建置 : 软件(2)

前言 今天我们要先来说一下打 Code 的地方,也就是会介绍一个非常好用的平台--Jupyter N...

# Day29--在某些commit之间再加些commit:我就是欲求不满,我就是强迫症!

加些新的commit Well,其实大部分的作法跟上一篇蛮相近的,我们都必须先进到commit纪录中...

day3 - 减少预期外的变数, 握在手里的就变多了

storage 选用: redis & scylla & mysql 简介 每件事情的走向...