【问题标题】:Set ViewPager's adapter via Data Binding通过数据绑定设置 ViewPager 的适配器
【发布时间】:2017-06-11 15:31:01
【问题描述】:

尝试使用 Android 的 Data Binding 来适配 ViewPager(控制可滑动的 Fragments)。

FooPagerAdapter.kt

class FooPagerAdapter(fm: Fragmentmanager, private val mFragments: List<BarFragment>) : FragmentStatePagerAdapter(fm) {
  override fun getItem(position: int): Fragment {
    return mFragments(position)
  }

  override fun getCount(): Int {
    return mFragments.size
  }
}

如果从 Activity 完成,它看起来像

  ..
  mFooViewPager.adapter = FooPagerAdapter(fragmentFamanager, fragmentsList)
  ..

问题:

现在如何将适配器功能传输到绑定文件以使用数据绑定更新片段 ViewPager?


编辑:

据我所知,它必须是这样的。

activity_foo.xml:

<android.support.v4.view.ViewPager
  ..
  app:fragments"${viewModel.fragments}"/>

然后在 FooViewModel.kt:

fun getFragments(): LiveData<List<BarFragment>>? = mFragments

companion object {
  @BindingAdapter("bind:fragments")
  fun setAdapter(pager: ViewPager, adapter: BarPagerAdapter) {
    pager.adapter = adapter
  }
}

编辑2:

决定直接使用ViewModel(不绑定)来设置ViewPager的适配器。

activity_foo.xml:

<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.foo.bar.viewmodels.FooViewModel"/>
    </data>
    ..
      <android.support.v4.view.ViewPager
          ..
          app:adapter="%{viewModel.adapter}"/>

FooViewModel.kt:

class FooViewModel(application: Application) : AndroidViewModel(application) {
  ..
  fun setAdapter(pager: ViewPager, fragments:List<PeriodFragment>) {
    pager.adapter = PeriodsPagerAdapter(mFragmentManager!!, periods)
  }

获取:

错误:...layout\activity_foo.xml:39 属性 'com.foo.bar:adapter' 未找到

【问题讨论】:

  • @tynn 好吧,我(我自己)想看一个最简单的例子:-)
  • 那么这个问题太宽泛了。有不同的可能方法可以做到这一点。您应该尝试一下,当您遇到问题时,请返回这里寻求一些解决方案。
  • @tynn 我已经更新了问题,请参阅编辑
  • 应该是app:adapter="@{viewModel.adapter}"。您需要使用 @ 而不是 %$ 以便识别绑定。

标签: android android-fragments kotlin


【解决方案1】:

@BindingAdapter 在 Java 中应该是静态的,因此使用 @JvmStatic 进行注释。此外,您应该跳过适配器定义中具有绑定属性的所有名称空间。此外,第二个参数需要引用您要设置的类型。在您的情况下,这是LiveData&lt;List&lt;BarFragment&gt;&gt;。然后就可以静态创建适配器了。

companion object {
  @JvmStatic
  @BindingAdapter("fragments")
  fun setAdapter(pager: ViewPager, fragments: LiveData<List<BarFragment>>) {
    pager.adapter = createAdapterForFragments(fragments)
  }
}

但如果fragmentsPagerAdapter,则根本不需要绑定适配器。作为默认实现,编译器会为属性查找给定的 setter 方法。因此,如果您使用app:adapter,则会自动使用setAdapter() 方法。因此,只需将此适配器定义放在布局中就足够了。

<android.support.v4.view.ViewPager
  ...
  app:adapter"@{viewModel.fragments}"/>

我建议使用后者并使用viewModel 设置适配器,而不是使用数据绑定。

ViewPagerTabLayout 的一些数据绑定便利,你会发现 ViewPagerDataBinding

【讨论】:

  • 好答案。但是你不觉得viewModel.fragments 有点奇怪吗?不应该换成适配器引用吗?
  • @Rehan 我期待fragmentsPagerAdapter 的一个实例。刚刚看到它实际上可能是LiveData 的一个实例。
  • 好的,使用 Gradle 选项获取完整的错误描述。事实证明,我还必须定义公共变量 adapter 以及 setAdapter - 才能正常工作。已解决。
  • 您从哪里获得FragmentManager 的实例?我什么都看不到。
  • @jesses.co.tt 非常感谢。回购已被删除。您现在会找到一个 fork 的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 2020-04-24
  • 2016-08-07
相关资源
最近更新 更多