Databinding not work together with viewbinding in Kotlin

若如初见. 提交于 2021-01-27 07:01:51

问题


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"

in app/build.gradle:

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

in my activity:

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)
            }
        })
    }

my 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"/>

After start app then success swipe viewpager2. And as result success show the next message:

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

nice. But qrBottonMainContainer not hide. Why?

P.S. If I remove this:

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

then success work.

why?


回答1:


You can't use them togheter in the same layout.

ViewBinding is a subset of what DataBinding can do and should be used if you want to replace libraries like ButterKnife, KotterKnife or KAE (Kotlin Android Extensions) but don't want to invest in databinding refactoring.

If you use DataBinding you already have the id reference of the views composing the layout in your binding object. Something like binding.myTextView.

Remember that:

  • The data binding library only processes data binding layouts created using the <layout> tag.
  • View binding doesn't support layout variables or layout expressions, so it can't be used to bind layouts with data in XML.

As per the documentation here

PS: In your specific case you can't use <layout> tags with ViewBinding




回答2:


Here solution without viewbinding

android {
    dataBinding {
        enabled = true
    }

in activity:

     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)
            }
        })
    }
}

And now it's work ONLY with databinding.

Nice.

Thanks @MatPag



来源:https://stackoverflow.com/questions/58557650/databinding-not-work-together-with-viewbinding-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!