【问题标题】:Android kotlin two way databinding on androidx.viewpager.widget.ViewPager::currentTabAndroid kotlin androidx.viewpager.widget.ViewPager::currentTab 上的两种方式数据绑定
【发布时间】:2020-07-31 21:15:02
【问题描述】:

我已尝试在 Internet 上使用教程在 androidx.viewpager.widget.ViewPager 上添加适配器以在当前选项卡上获得两种方式的数据绑定。 我到了那个适配器

// adapter file
@BindingAdapter("currentTab")
@JvmStatic
fun setTab(pager: ViewPager, itemLiveData: MutableLiveData<Int>) {
   itemLiveData.value?.let {

        if (pager.currentItem != it) {
            pager.setCurrentItem(it, true)
        }
    }
}

@InverseBindingAdapter(attribute = "currentItem")
@JvmStatic
fun getTab(pager: ViewPager) = pager.currentItem
<!-- layout file -->
<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginTop="70dp"
    app:adapter="@{viewModel.adapter}"
    app:currentTab="@={viewModel.currentItem}"
    app:layout_constraintBottom_toTopOf="@+id/tabLayout"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

当我尝试构建应用程序时,我收到了这个错误(使用 --stacktrace 选项):

Could not find event 'currentItemAttrChanged' on View type 'androidx.viewpager.widget.ViewPager'

我找不到任何教程/答案,所以我在这里询问是否有人对此有答案。 谢谢

编辑: 我尝试使用@InverseBindingAdapter(attribute = "currentTab"),但它给了我同样的错误:Could not find event 'currentTabAttrChanged' on View type 'androidx.viewpager.widget.ViewPager'

问题是currentTab更改时我不知道事件名称调用。

【问题讨论】:

    标签: android kotlin android-viewpager android-databinding 2-way-object-databinding


    【解决方案1】:

    听起来您想从 ViewModel 内部收到有关 ViewPager 中页面更改的通知。在这种情况下,正如 Benoit Guina 指出的那样,您可以像这样绑定 OnPageChangeListener。

    在您的 xml 文件中,像这样表示您的视图寻呼机:

        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:setPageChangeListener="@{myViewModel.pageChangeCallback}" />
    

    请注意,我们有一个名为 setPageChangeListener 的自定义属性。提供给该属性的值是从我们的视图模型中获得的。我们在 BindingAdapters 文件中定义自定义属性,如下所示:

    /**
     * set listener for view pager changes
     */
    @BindingAdapter("setPageChangeListener")
    fun ViewPager2.setPageChangeListener(pageChangeListener: ViewPager2.OnPageChangeCallback) {
        registerOnPageChangeCallback(pageChangeListener)
    }
    

    最后我们在视图模型中定义了监听器。因为侦听器位于视图模型中,所以当视图分页器发生更改时,它可以修改该视图模型中的属性。

    /**
     * In the View Model
     */
    val currentPageLiveData = MutableLiveData(0)
    
    val pageChangeCallback = object: ViewPager2.OnPageChangeCallback() {
        override fun onPageSelected(position: Int) {
            super.onPageSelected(position)
            currentPageLiveData.value = position
        }
    }
    

    【讨论】:

      【解决方案2】:

      您希望可绑定的每个属性都必须与 @BindingAdapter 的名称匹配。
      Gradle 找不到@BindingAdapter("currentTab")

      你可以
      - 写currentTab BindingAdapter + 它的InverseBindingAdapter 来观察它。
      - 或者一个快速的解决方案:绑定一个简单的ViewPager.OnPageChangedListener 并从中实现

      @BindingAdapter("onPageChangeListener")
      fun ViewPager.bindOnPageChangeListener(listener: ViewPager.OnPageChangeListener) {
          addOnPageChangeListener(listener)
      }
      
      <!-- layout file -->
      <androidx.viewpager.widget.ViewPager
          android:id="@+id/viewPager"
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:layout_marginTop="70dp"
          app:adapter="@{viewModel.adapter}"
          app:onPageChangeListener="@{viewModel.onPageChangeListener}"
          app:layout_constraintBottom_toTopOf="@+id/tabLayout"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent">
      

      【讨论】:

      • 无法使用这个应用程序:onPageChangeListener 即使在创建@BindingAdapter 之后
      猜你喜欢
      • 2018-02-08
      • 2016-02-27
      • 1970-01-01
      • 2019-02-24
      • 2018-03-16
      • 2020-05-08
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多