在一个项目中,我们正在使用Material Design Components的TabLayoutViewPager。有14个标签,我们希望在TabLayout中一次显示其中7个标签。选项卡的内容非常狭窄,以至于我们确定7个不会太多,并且设计团队希望无论屏幕宽度如何都显示一致数量的选项卡(选项卡代表一周中的几天)。

没有一个预定义的选项卡模式似乎与此相匹配:

  • MODE_FIXEDMODE_AUTO通过显示所有选项卡
  • 来控制可见选项卡的数量。
  • MODE_SCROLLABLE允许选项卡滚动...但是然后我们无法控制可见选项卡的数量

  • 有没有一种方法可以解决此问题,而不会涉及无法维护的黑客,例如在运行时使用反射来修补tabPaddingStart,或遍历选项卡小部件并调整其LayoutParams

    我看过this question,但是缺少解释-尤其是,尚不清楚如何在运行时将app:tabMaxWidth用作动态值。同样,这个问题是关于较旧的设计支持库的,该库可能与MDC的实现有所不同。

    最佳答案

    有几种方法可以显示固定数量的选项卡,而与可以使用的屏幕宽度无关,但是所需的功能实际上已被锁定。最值得注意的是,如果TabLayout中的getTabMinWidth()不是私有(private)的,一个简单的解决方案是在自定义TabLayout View 中覆盖该方法。

    以下是Eugen Pechanec在上面的注释中建议的内容,可能正是这些内容,其中涉及选项卡的自定义 View 。

    首先是基本布局。

    activity_main.xml
    tabMinWidthtabPaddingEndtabPaddingStart都设置为0dptabMinWidth的默认值可能太大而无法满足我们的需求。可以将填充设置为零以外的其他值,但是我宁愿在选项卡的自定义 View 中进行处理。

    ViewPager并没有真正发生任何事情。

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        tools:context=".MainActivity">
    
        <androidx.viewpager.widget.ViewPager
            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:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:tabMinWidth="0dp"
                app:tabMode="scrollable"
                app:tabPaddingEnd="0dp"
                app:tabPaddingStart="0dp" />
        </androidx.viewpager.widget.ViewPager>
    </androidx.appcompat.widget.LinearLayoutCompat>
    

    custom_tab.xml
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@android:id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Tab x"
            android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
    
    <!--    If an icon is needed. -->
    <!--    <ImageView-->
    <!--        android:id="@android:id/icon"-->
    <!--        android:layout_width="48dp"-->
    <!--        android:layout_height="48dp"-->
    <!--        android:scaleType="centerCrop"-->
    <!--        android:src="@drawable/ic_launcher_foreground" />-->
    </LinearLayout>
    

    MainActivity.kt

    选项卡被一一设置到自定义 View 中,然后被一一加载到TabLayout中。自定义 View 的最小宽度设置为TabLayout宽度的1/7。设置最小宽度就足够了,因为假定所需的宽度将始终小于或等于总宽度的1/7。
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val tabLayout = findViewById<TabLayout>(R.id.tabs)
            tabLayout.doOnLayout {
                val tabWidth = tabLayout.width / 7
                for (i in 1..14) {
                    tabLayout.newTab().run {
                        setCustomView(R.layout.custom_tab)
                        customView?.minimumWidth = tabWidth
                        setText("Tab $i")
                        tabLayout.addTab(this)
                    }
                }
            }
    
        }
    }
    

    如果仍然使用自定义选项卡,我认为这是一个合理的解决方案。但是,它比遍历TabLayout子项和设置宽度更好(IMO)。

    最后,有几张照片:

    android - 如何为固定数量的可滚动标签配置TabLayout?-LMLPHP

    android - 如何为固定数量的可滚动标签配置TabLayout?-LMLPHP

    关于android - 如何为固定数量的可滚动标签配置TabLayout?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58456917/

    10-15 18:05