【问题标题】:Data binding while using fragment manager使用片段管理器时的数据绑定
【发布时间】:2019-09-03 21:47:45
【问题描述】:

我最近开始学习 Android 中的数据绑定,我了解了基础知识,但是当我尝试做一些更复杂的数据绑定时,例如使用 viewpager 适配器(使用片段管理器)进行视图寻呼机的数据绑定时,我并不完全了解如何使用视图的片段管理器(在我的情况下这是一个片段,我使用子片段管理器)。 我发现了一些不完整的示例和解决方案,但似乎没有任何效果。

这是我目前的代码:

  • 首页片段

    class HomeFragment : Fragment() {
    
    lateinit var binding : FragmentHomeBinding
    lateinit var viewModel : HomeViewModel
    
    lateinit var viewPager : ViewPager
    lateinit var tabs : TabLayout
    
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
        val view = binding.root
        viewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
        setupViews(view)
    
        return view
    }
    
    fun setupViews(view : View){
        tabs = view.findViewById(R.id.tabs)
        viewPager = view.findViewById(R.id.pager)
    
        val childFragmentManager = childFragmentManager
    
        viewPager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
    
    
        tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab) {
                viewPager.currentItem = tab.position
            }
    
            override fun onTabUnselected(tab: TabLayout.Tab) {
    
            }
    
            override fun onTabReselected(tab: TabLayout.Tab) {
    
            }
        })
    }
    

    }

  • home_fragment.xml

    <data>
    
        <variable
            name="fm"
            type="androidx.fragment.app.FragmentManager" />
    
        <variable
            name="viewModel"
            type=".HomeViewModel" />
    
        <variable
            name="adapter"
            type=".HomeViewPagerAdapter" />
    
    </data>
    
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
    
        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMaxWidth="0dp"
            app:setupWithViewPager="@{pager}"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" >
    
            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/upcoming_tab"/>
            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/synced_items_tab"/>
    
        </com.google.android.material.tabs.TabLayout>
    
    
        <androidx.viewpager.widget.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:adapter="@{adapter(fm)}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tabs" />
    
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

  • 主视图模型

    类 HomeViewModel: ViewModel(){

    @BindingAdapter("adapter")
    fun setAdapter(pager: ViewPager, fm: FragmentManager) {
        pager.adapter = HomeViewPagerAdapter(pager.context,fm)
    }
    

    }

【问题讨论】:

    标签: android kotlin data-binding fragment fragmentmanager


    【解决方案1】:

    我将尝试提供另一种方法来归档您正在查找的内容,同时给出一些简短的解释。我希望最后你能从中受益。

    在您的&lt;data&gt; 中只留下ViewModelAdapter

    <data>
    
        <variable
            name="viewModel"
            type=".HomeViewModel" />
    
        <variable
            name="adapter"
            type=".HomeViewPagerAdapter" />
    
    </data>
    

    需要设置那些&lt;variable .../&gt; 值。您可以使用 binding 变量来做到这一点,例如:

    # inside onCreate
    binding.viewModel = viewModel
    binding.adapter = HomeViewPager(context, fm)
    

    ViewModel 不应该负责创建适配器,甚至更不了解上下文或片段管理器等 Android 组件,尽量使其依赖项与 Fragment/Activity 的细节保持最低限度。如果这是它目前正在做的唯一事情,您可以安全地摆脱它。

    现在,对于@BindingAdapter,我建议你把它放在里面,反对并用@JvmStatic注释它。你可以把它写在一个单独的类中,然后把你所有的 @BindingAdapters 放在里面:

    object BindingAdapters {
    
        @JvmStatic
        @BindingAdapter("adapter")
        fun ViewPager.bindAdapter(adapter: HomeViewPagerAdapter) {
             this.adapter = adapter
        }
    
    }
    

    您的ViewPager 的适配器将被自动设置。

    但是,我认为这不值得。您已经在片段中引用了ViewPager,您可以在那里设置adapter

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 2018-06-24
      • 1970-01-01
      • 2010-09-10
      相关资源
      最近更新 更多