Как я могу использовать привязку данных через XML для изменения текста вкладок, настроенного с помощью TabLayoutMediator? - PullRequest
0 голосов
/ 02 августа 2020

У меня есть две вкладки в 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()
        })
    }

Как видите, я наблюдаю userDetails из моей ViewModel. Это класс данных, содержащий эти два поля: подписчики и подписки (оба являются целыми числами). Моя модель просмотра имеет только userDetails LiveData и блок инициализации для выборки удаленных данных.

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>

Это есть ли способ наблюдать от userDetails до XML и изменять текст моих вкладок, который установлен с помощью TabLayoutMediator, что позволяет избежать необходимости использовать viewmodel.userDetails.observe(...) в моем коде фрагмента? Если есть, как мне этого добиться?

1 Ответ

0 голосов
/ 02 августа 2020

используйте TabItem внутри TabLayout вместо расширения меню

<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>
...