• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • Data binding 入坑筆記二進階篇之雙向綁定

    標簽: android  數據綁定

    Data binding 入坑筆記一入門篇

    上一篇介紹了Data binding的基礎用法,你可能會想這也太基礎了,只支持前置數據的綁定,一旦數據變化了UI都監聽不到。不要著急,這一篇就來講到databinding的雙向綁定用法。

    0.舉個例子

    我們用一個輸入控件EditText和一個文本控件TextView來舉個栗子,我們想要在TextView要獲取文本框內容,原始寫法首先獲取兩個控件的對象,然后設置輸入框監聽對象,最后賦值給TextView做顯示,算了算需要寫三步呢
    這里寫圖片描述

    我們來看看Data Binding的代碼,只需要把對象綁定進去就好了

    public class TwowayActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_twoway);
            ActivityTwowayBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_twoway);
            binding.setStudent(new Student());
        }
    }
    <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="student" 
                type="com.jie.databindingsimple.entity.Student"/>
        </data>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="請輸入內容"
                android:text="@={student.name}"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@{student.name}"/>
        </LinearLayout>
    </layout>

    1. Observable Binding

    Data Binding本身是不支持雙向綁定的,我們想要實現雙向綁定首先要改造一下實體類。讓實體類繼承BaseObservable,來看例子

    public class Student extends BaseObservable {
        private String name;
        private String className;
    
        @Bindable
        public String getName() {
            return name;
        }
    
        @Bindable
        public String getClassName() {
            return className;
        }
    
        public void setName(String name) {
            this.name = name;
            notifyPropertyChanged(BR.name);
        }
    
        public void setClassName(String className) {
            this.className = className;
            notifyPropertyChanged(BR.className);
        }
    }

    BR是編譯階段生成的一個類,功能與 R.java 類似,用 @Bindable標記過 getter方法會在BR中生成一個靜態常量。

    public class BR {
            public static final int _all = 0;
            public static final int className = 1;
            public static final int name = 2;
            public static final int student = 3;
            public static final int user = 4;
    }

    setter方法里我們需要用notifyPropertyChanged方法來更新對象。

    還有另一種適用于POJO的寫法,這種寫法不需要繼承BaseObservable,不過每個成員變量都要new一個ObservableField對象。

    public class Teacher {
        public final ObservableField<String> name = new ObservableField<>();
        public final ObservableField<String> className = new ObservableField<>();
        public final ObservableInt age = new ObservableInt();
    }

    2. xml寫法

    如果想在輸入的時候給變量賦值,則需要用到@={}這個操作符,{}里面是我們想要賦值的對象

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入內容"
        android:text="@={student.name}"/>

    3.原理解析

    InverseBindingListener是事件發生時觸發的監聽器,所有雙向綁定,最后都是通過這個接口來observable改變的,各種監聽,比如TextWatcherOnCheckedChange,都是間接通過這個接口來通知的。在ActivityTwowayBinding的源碼中我們可以找到這個方法片段。

        // values
        // listeners
        // Inverse Binding Event Handlers
        private android.databinding.InverseBindingListener mboundView1androidTextAttrChanged = new android.databinding.InverseBindingListener() {
            @Override
            public void onChange() {
                // Inverse of student.name
                //         is student.setName((java.lang.String) callbackArg_0)
                java.lang.String callbackArg_0 = android.databinding.adapters.TextViewBindingAdapter.getTextString(mboundView1);
                // localize variables for thread safety
                // student
                com.jie.databindingsimple.entity.Student student = mStudent;
                // student.name
                java.lang.String studentName = null;
                // student != null
                boolean studentJavaLangObjectNull = false;
    
                studentJavaLangObjectNull = (student) != (null);
                if (studentJavaLangObjectNull) {
                    student.setName(((java.lang.String) (callbackArg_0)));
                }
            }
        };

    我們通過java.lang.String callbackArg_0 = android.databinding.adapters.TextViewBindingAdapter.getTextString(mboundView1);獲取到EditText上輸入的值,來看看getTextString方法

        @InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
        public static String getTextString(TextView view) {
            return view.getText().toString();
        }

    InverseBindingAdapter用于關聯某個用于接收View變更的方法,有兩個參數attribute描述和event事件,獲取到數據后我們拿到student對象,然后給他賦值student.setName(((java.lang.String) (callbackArg_0)));

    4. 屬性改變監聽

    如果有兩個輸入框,我們要監聽輸入對象的改變怎么辦,如下:
    這里寫圖片描述

    我們可以利用Observable中的addOnPropertyChangedCallback來實現。先來看看Observable類,里面有添加回調、刪除回調等方法。

    package android.databinding;
    
    public interface Observable {
        void addOnPropertyChangedCallback(Observable.OnPropertyChangedCallback var1);
    
        void removeOnPropertyChangedCallback(Observable.OnPropertyChangedCallback var1);
    
        public abstract static class OnPropertyChangedCallback {
            public OnPropertyChangedCallback() {
            }
    
            public abstract void onPropertyChanged(Observable var1, int var2);
        }
    }

    onCreate中實現添加callback

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_twoway);
            ActivityTwowayBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_twoway);
            Student student = new Student();
            binding.setStudent(student);
            student.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
                @Override
                public void onPropertyChanged(Observable observable, int i) {
                    switch (i) {
                        case BR.name:
                            Toast.makeText(TwowayActivity.this, "name", Toast.LENGTH_SHORT).show();
                            break;
                        case BR.className:
                            Toast.makeText(TwowayActivity.this, "classname", Toast.LENGTH_SHORT).show();
                            break;
                    }
                }
            });
        }

    5. 雙向綁定場景范圍

    目前雙向綁定僅支持如text,checked,year,month,hour,rating,progress等綁定。

    完整代碼看這里

    版權聲明:本文為anthony_3原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/anthony_3/article/details/78576700

    智能推薦

    android -------- Data Binding的使用(一)

    Google推出自己官方的數據綁定框架Data Binding Library 已經很久了,很多企業也在使用 面試的時候也有問到,所以也去學習了一番,特來分享一下,希望對各位有所幫助   描述: Data Binding 是把數據直接綁定到 XML 文件上,并能實現自動刷新。 Data Binding 減少了代碼的耦合性,一些如 findViewById、setText 之類的操作都可以...

    Android---Data Binding使用入門

    Android---Data Binding使用入門 2016年09月22日 14:41:14 閱讀數:466 一直沒使用過Data Binding,今天就來學習一下,有興趣的朋友可以直接看官網的介紹Data Binding 準備工作 首先要在build.gradle中添加一句 1 2 3 添加的位置是這樣的 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 然后準備好...

    UI5的Data binding

    學習了解一下UI5的數據binding UI5作為一個成熟的企業級UI開發框架,其最大的特點就是遵循MVC的設計,也就是將代碼邏輯清晰地區分為數據源(model) - UI(view) - 應用邏輯(controller)這三部分。數據binding就是model和view之間如何交互。 UI5的數據binding主要有三種方式: Property binding Aggregation bind...

    c#中的data binding

    Data Binding Overview WPF用data binding來創建UI和數據的關聯。其中數據的來源可以是common language runtime objects或者是XML. wpf中的data binding相對于傳統的模型有很多優勢: 1. UI的大多數屬性(properties)都是支持data binding的 2. binding可以讓UI變得更加靈活 3. UI和...

    WPF中的Data Binding調試指南

    點擊藍字“大白技術控”關注我喲 加個“星標★”,每日良時,好文必達! WPF中的Data Binding如何Debug? 大家平時做WPF開發,相信用Visual studio的小伙伴比較多。XAML代碼曾經在某些特殊版本的Visual Studio中是可以加斷點進行調試的,不過目前多數版本都不支持在XAML加斷點來調試。 那如果自己需要綁定的 Pr...

    猜你喜歡

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡