將版面配置視圖與架構元件建立繫結

AndroidX 程式庫包含架構 元件 來設計出功能完善、可供測試及維護的應用程式。 資料繫結程式庫可與架構完美搭配運作 進一步簡化 使用者介面的開發作業。應用程式中的版面配置 能繫結至架構元件中的資料,協助您 管理 UI 控制器的生命週期,並在資料變更時通知 UI。

本頁說明如何將架構元件整合至應用程式, 並充分運用資料繫結程式庫。

使用 LiveData 向使用者介面傳送資料變更通知

您可以將 LiveData 物件做為 資料繫結來源,以便自動向 UI 通知 資料。如要進一步瞭解此架構元件,請參閱 LiveData 總覽頁面

與導入 Observable可觀察 欄位LiveData 物件得知訂閱資料的觀察器的生命週期 並輸入變更內容這些知識可帶來許多好處,詳情請參閱 的優點 LiveData。 在 Android Studio 3.1 以上版本中,您可以替換可觀察欄位 在資料繫結程式碼中使用 LiveData 物件。

如要搭配繫結類別使用 LiveData 物件,您需要指定 生命週期擁有者負責定義 LiveData 物件的範圍。下列 範例會在繫結類別之後,將活動指定為生命週期擁有者 已完成執行個體化:

Kotlin

class ViewModelActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // Inflate view and obtain an instance of the binding class.
        val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)

        // Specify the current activity as the lifecycle owner.
        binding.setLifecycleOwner(this)
    }
}

Java

class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Inflate view and obtain an instance of the binding class.
        UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

        // Specify the current activity as the lifecycle owner.
        binding.setLifecycleOwner(this);
    }
}

您可以使用 ViewModel 元件 (如下一節所述),將資料繫結至版面配置。在 ViewModel 元件中 可以使用 LiveData 物件來轉換資料或合併多個資料 資料來源以下範例說明如何轉換 ViewModel 中的資料:

Kotlin

class ScheduleViewModel : ViewModel() {
    val userName: LiveData

    init {
        val result = Repository.userName
        userName = Transformations.map(result) { result -> result.value }
    }
}

Java

class ScheduleViewModel extends ViewModel {
    LiveData username;

    public ScheduleViewModel() {
        String result = Repository.userName;
        userName = Transformations.map(result, result -> result.value);
    }
}

使用 ViewModel 管理 UI 相關資料

資料繫結程式庫可與 ViewModel 元件。ViewModel 會顯示版面配置觀察的資料,並回應其變更。使用 具有資料繫結程式庫的 ViewModel 元件可讓您移動 UI 邏輯 再進到元件中,這比較容易測試資料 繫結程式庫可確保檢視畫面繫結和取消繫結 原始碼其餘的工作大多是確保 提供正確的資料如要進一步瞭解這個架構 元件,請參閱 ViewModel 總覽頁面

如要搭配使用 ViewModel 元件與資料繫結程式庫,您必須 將元件執行個體化 (繼承自 ViewModel 類別,取得 繫結類別的例項,並將 ViewModel 元件指派給 繫結屬性。以下範例說明如何使用 新增元件:

Kotlin

class ViewModelActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // Obtain the ViewModel component.
        val userModel: UserModel by viewModels()

        // Inflate view and obtain an instance of the binding class.
        val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)

        // Assign the component to a property in the binding class.
        binding.viewmodel = userModel
    }
}

Java

class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Obtain the ViewModel component.
        UserModel userModel = new ViewModelProvider(this).get(UserModel.class);

        // Inflate view and obtain an instance of the binding class.
        UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

        // Assign the component to a property in the binding class.
        binding.viewmodel = userModel;
    }
}

在版面配置中,指派 ViewModel 元件的屬性和方法 透過繫結運算式調整至對應的檢視畫面,如下所示 範例:

<CheckBox
    android:id="@+id/rememberMeCheckBox"
    android:checked="@{viewmodel.rememberMe}"
    android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />

使用可觀察 ViewModel 來進一步控制繫結轉接器

您可以使用 ViewModel 會實作 Observable 介面 以通知其他人員 有關資料變更的應用程式元件,類似使用 LiveData 物件。

針對某些情況下,您可能會想使用 ViewModel 元件:實作 Observable 即使失去生命週期,也依然會採用 LiveData 物件介面 管理各項功能LiveData使用會執行以下動作的 ViewModel 元件: 實作 Observable 可讓您進一步控制 API 中的繫結轉接器 應用程式。例如,這個模式可讓你進一步控制通知 資料變更時;還能讓您指定自訂方法 雙向資料繫結的屬性值。

如要實作可觀察的 ViewModel 元件,您必須建立 繼承自 ViewModel 類別,並實作 Observable 存取 API您可以在觀察器訂閱或訂閱時,提供自訂邏輯 取消訂閱通知 addOnPropertyChangedCallback()敬上 和 removeOnPropertyChangedCallback() 方法。您也可以提供自訂邏輯,在屬性變更時執行 這個 notifyPropertyChanged()敬上 方法。以下程式碼範例顯示如何實作可觀察物件 ViewModel:

Kotlin

/**
 * A ViewModel that is also an Observable,
 * to be used with the Data Binding Library.
 */
open class ObservableViewModel : ViewModel(), Observable {
    private val callbacks: PropertyChangeRegistry = PropertyChangeRegistry()

    override fun addOnPropertyChangedCallback(
            callback: Observable.OnPropertyChangedCallback) {
        callbacks.add(callback)
    }

    override fun removeOnPropertyChangedCallback(
            callback: Observable.OnPropertyChangedCallback) {
        callbacks.remove(callback)
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    fun notifyChange() {
        callbacks.notifyCallbacks(this, 0, null)
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes must be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    fun notifyPropertyChanged(fieldId: Int) {
        callbacks.notifyCallbacks(this, fieldId, null)
    }
}

Java

/**
 * A ViewModel that is also an Observable,
 * to be used with the Data Binding Library.
 */
class ObservableViewModel extends ViewModel implements Observable {
    private PropertyChangeRegistry callbacks = new PropertyChangeRegistry();

    @Override
    protected void addOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.add(callback);
    }

    @Override
    protected void removeOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.remove(callback);
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    void notifyChange() {
        callbacks.notifyCallbacks(this, 0, null);
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes must be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    void notifyPropertyChanged(int fieldId) {
        callbacks.notifyCallbacks(this, fieldId, null);
    }
}

其他資源

如要進一步瞭解資料繫結,請參閱以下資源 其他資源