簡體   English   中英

數據綁定不能與 Kotlin 中的視圖綁定一起使用

[英]Databinding not work together with viewbinding in Kotlin

Android Studio 3.6

build.gradle:

buildscript {
    ext.kotlin_version = '1.3.50'
    repositories {
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.0-beta01'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

在 app/build.gradle 中:

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

在我的活動中:

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager2.widget.ViewPager2

import com.myproject.BuildConfig
import com.myproject.R
import com.myproject.adapter.CustomFragmentStateAdapter
import com.myproject.databinding.QrBluetoothSwipeActivityBinding
import com.myproject.ui.fragment.BluetoothPageFragment
import com.myproject.ui.fragment.QrPageFragment
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableInt

class QRBluetoothSwipeActivity : AppCompatActivity() {
    private lateinit var viewBinding: QrBluetoothSwipeActivityBinding
    var positionObservable = ObservableInt()

    companion object {
        private val TAG = QRBluetoothSwipeActivity::class.java.name
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)  

         // databinding init
        val binding = DataBindingUtil.setContentView<QrBluetoothSwipeActivityBinding>(
            this, R.layout.qr_bluetooth_swipe_activity
        )
        binding.setHandler(this)

        // viewbinding init
        viewBinding = QrBluetoothSwipeActivityBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)

        init()
    }

 private fun init() {
        val customFragmentStateAdapter = CustomFragmentStateAdapter(this)
        customFragmentStateAdapter.addFragment(QrPageFragment())
        customFragmentStateAdapter.addFragment(BluetoothPageFragment())
        viewBinding.viewPager2.adapter = customFragmentStateAdapter

        viewBinding.viewPager2.registerOnPageChangeCallback(object :
            ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                if (BuildConfig.DEBUG) {
                    Log.d(TAG, "registerOnPageChangeCallback: position = $position")
                }
                positionObservable.set(position)
            }
        })
    }

我的qr_bluetooth_swipe_activity.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">

    <data>

        <import type="android.view.View" />

        <variable
            name="handler"
            type="com.myproject.actviity.QRBluetoothSwipeActivity" />

    </data>

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

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewPager2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/bottonContainer"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/bottonContainer"
            android:layout_width="0dp"
            android:layout_height="104dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/qrBottonMainContainer"
                android:layout_width="0dp"
                android:layout_height="104dp"
                android:visibility="@{handler.positionObservable == 0 ? View.GONE: View.VISIBLE}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"/>

啟動應用程序后,成功滑動viewpager2 結果成功顯示下一條消息:

10-25 14:25:24.991 D/com.myproject.actviity.QRBluetoothSwipeActivity(23012): registerOnPageChangeCallback: position = 0

好的。 但是qrBottonMainContainer沒有隱藏。 為什么?

PS如果我刪除這個:

viewBinding = QrBluetoothSwipeActivityBinding.inflate(layoutInflater)
setContentView(viewBinding.root)

然后成功工作。

為什么?

您不能在同一布局中同時使用它們。

ViewBindingDataBinding可以做的一個子集,如果您想替換ButterKnifeKotterKnife或 KAE(Kotlin Android 擴展)等庫但不想投資於數據綁定重構,則應該使用 ViewBinding。

如果您使用DataBinding ,您已經在binding object 中擁有組成布局的視圖的 id 引用。 類似binding.myTextView的東西。

請記住:

  • 數據綁定庫僅處理使用<layout>標記創建的數據綁定布局。
  • 視圖綁定不支持布局變量或布局表達式,因此不能用於將布局與 XML 中的數據綁定。

根據此處的文檔

PS:在您的特定情況下,您不能將<layout>標簽與ViewBinding一起使用

這里沒有視圖綁定的解決方案

android {
    dataBinding {
        enabled = true
    }

活動中:

     import android.os.Bundle
        import android.util.Log
        import androidx.appcompat.app.AppCompatActivity
        import androidx.viewpager2.widget.ViewPager2

        import com.myproject.BuildConfig
        import com.myproject.R
        import com.myproject.adapter.CustomFragmentStateAdapter
        import com.myproject.ui.fragment.BluetoothPageFragment
        import com.myproject.ui.fragment.QrPageFragment
        import androidx.databinding.DataBindingUtil
        import androidx.databinding.ObservableInt
        import com.myproject.databinding.QrBluetoothSwipeActivityBinding

    class QRBluetoothSwipeActivity : AppCompatActivity() {
        private lateinit var dataBinding: QrBluetoothSwipeActivityBinding
        var positionObservable = ObservableInt()

        companion object {
            private val TAG = QRBluetoothSwipeActivity::class.java.name
        }

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            dataBinding = DataBindingUtil.setContentView<QrBluetoothSwipeActivityBinding>(
                this, R.layout.qr_bluetooth_swipe_activity
            )
            dataBinding.setHandler(this)
            init()
        }

        private fun init() {
        val customFragmentStateAdapter = CustomFragmentStateAdapter(this)
        customFragmentStateAdapter.addFragment(QrPageFragment())
        customFragmentStateAdapter.addFragment(BluetoothPageFragment())
        dataBinding.viewPager2.adapter = customFragmentStateAdapter

        dataBinding.viewPager2.registerOnPageChangeCallback(object :
            ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                if (BuildConfig.DEBUG) {
                    Log.d(TAG, "registerOnPageChangeCallback: position = $position")
                }
                positionObservable.set(position)
            }
        })
    }
}

現在它只適用於 databinding

好的。

謝謝@MatPag

如果您想在單個布局中同時使用視圖綁定和數據綁定,您只需要使用數據綁定,因為視圖綁定是數據綁定的子集,數據綁定提供視圖綁定的功能。

兩者的區別在於視圖綁定只針對視圖引用,不用於綁定 UI 和數據源。

android {
buildFeatures {
    dataBinding true
  }
}




   <layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
    <variable
        name="viewmodel"
        type="com.myapp.data.ViewModel" />
</data>

</layout>




val dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
dataBinding.executePendingBindings()
dataBinding.tvName.text="View Binding"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM