【问题标题】:How can I use data binding through XML to change tabs' text configured with TabLayoutMediator?如何通过 XML 使用数据绑定来更改使用 TabLayoutMediator 配置的选项卡文本?
【发布时间】:2020-08-02 21:41:51
【问题描述】:

我的 ViewPager2 中有两个要配置的选项卡。最初,它有一个默认的空文本。收到远程服务器的 API 响应后,我想将选项卡的文本更改为收到的数据。

我的包含 ViewPager2 和 TabLayout 的片段如下。

class UserDetailsFragment : Fragment() {
    private lateinit var binding: FragUserDetailsBinding
    private val args: UserDetailsFragmentArgs by navArgs()
    private val viewmodel by viewModels<UserDetailsViewModel> {
        UserDetailsViewModelFactory(
            requireActivity().application,
            args.username
        )
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragUserDetailsBinding.inflate(inflater, container, false)
        binding.viewmodel = viewmodel
        binding.lifecycleOwner = this
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupViewPager()
        observeUserDetails()
    }

    private fun setupViewPager() {
        val viewPagerAdapter =
            UserFollowPagerAdapter(childFragmentManager, viewLifecycleOwner.lifecycle)
        binding.fragDetailsPager.adapter = viewPagerAdapter
        binding.fragDetailsPager.offscreenPageLimit = 1
        TabLayoutMediator(binding.fragDetailsTabLayout, binding.fragDetailsPager) { tab, position ->
            when (position) {
                0 -> "-"
                1 -> "-"
            }
        }.attach()
    }

    private fun observeUserDetails() {
        viewmodel.userDetails.observe(viewLifecycleOwner, Observer {
            binding.fragDetailsTabLayout.getTabAt(0)?.text = it.followers.toString()
            binding.fragDetailsTabLayout.getTabAt(1)?.text = it.following.toString()
        })
    }

如您所见,我在 ViewModel 中观察 userDetails。它是一个包含这两个字段的数据类:followers 和 following(都是整数)。我的 ViewModel 只有 userDetails LiveData 和一个用于获取远程数据的 init 块。

class UserDetailsViewModel(application: Application, private val username: String) :
    AndroidViewModel(application) {
    private var _userDetails = MutableLiveData<UserDetails>()
    val userDetails: LiveData<UserDetails>
        get() = _userDetails
    
    init {
        viewModelScope.launch {
            try {
                _userDetails.value = userRepository.getUserDetails(username).toDomainModel()
            } catch (e: Exception) {
                
            }
        }
    }
}

我的片段 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"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewmodel"
            type="com.mobile.githubuser.viewmodel.UserDetailsViewModel" />
    </data>
            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="?android:colorBackground">

                
                <com.google.android.material.tabs.TabLayout
                    android:id="@+id/frag_details_tab_layout"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/keyline_5"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/frag_details_details" />

                <View
                    android:id="@+id/frag_details_tab_layout_underline"
                    android:layout_width="0dp"
                    android:layout_height="1dp"
                    android:alpha="0.3"
                    android:background="?attr/colorNeutral"
                    android:translationY="-1dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/frag_details_tab_layout" />

                <androidx.viewpager2.widget.ViewPager2
                    android:id="@+id/frag_details_pager"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/frag_details_tab_layout" />

                
            </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

有没有办法通过 XML 观察 userDetails 并更改通过 TabLayoutMediator 设置的标签文本,从而避免在我的 Fragment 代码中使用 viewmodel.userDetails.observe(...)?如果有,我该如何实现?

【问题讨论】:

    标签: android android-viewpager android-databinding android-tablayout


    【解决方案1】:

    TabLayout 中使用TabItem 而不是菜单膨胀

    <com.google.android.material.tabs.TabLayout
                    android:id="@+id/frag_details_tab_layout"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/keyline_5"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/frag_details_details" >
    
             <com.google.android.material.tabs.TabItem
                android:id="@+id/tabFollowers"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{viewmodel.userDetails.followers}"
                android:icon="@drawable/ic_home" />
    
            <com.google.android.material.tabs.TabItem
                android:id="@+id/tabFollowing"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{viewmodel.userDetails.following}"
                 />
    
    </com.google.android.material.tabs.TabLayout>
    

    【讨论】:

    • 但是使用ViewPager2,我必须通过TabLayoutMediator以某种方式配置文本(参考这个documentation
    • 这也不编译。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多