平板电脑设备上的标签页未完​​全显示[使用android.support.design.widget.TabLayout]


202

我有设置选项卡 UPDATE 29/05/2015 这篇文章。在Nexus 4移动设备上,标签页全角显示,但在nexus 7平板电脑上,标签页在中间显示,而不能覆盖整个屏幕宽度。

Nexus 7屏幕截图 Nexus7 Nexus 4屏幕截图 Nexus 4


在6个小时内一直在为完全相同的问题而苦苦挣扎,但我没有意识到它仅在选项卡上存在问题...认为在stackoverflow上应该有功能可以将问题
投票

请尝试为问题添加更多标签...(这样将对像我这样的人有所帮助),因为这个问题是我在Google搜索列表的第三页上找到的
Shirish Herwade

Answers:


594

从Kaizie借来的 “更简单”的答案只会app:tabMaxWidth="0dp"在您的TabLayoutxml中添加:

<android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMaxWidth="0dp"
            app:tabGravity="fill"
            app:tabMode="fixed" />

19
如果我需要它可滚动怎么办?更改tabMode以支持滚动将打破此解决方案。
Tiago

3
滚动解决方案?
sunlover3

5
嗨..我尝试添加它。但单个选项卡未占据选项卡布局的整个宽度。
拉胡尔

3
如果未设置tabMode,则此解决方案也适用。可滚动的tapMode似乎不支持填充重力和0dp最大宽度的功能。
Julio Mendoza 2016年

3
为什么会发生呢?这是默认行为吗?还是我不好用的东西?将标签设置在中间是指南的一部分吗?使用3个以上标签时,这对我而言不会发生。仅用于2个标签。
Android开发人员

91

我遇到了同样的问题,检查了TabLayout样式,发现它的默认样式Widget.Design.TabLayout具有不同的实现(正常,横向和sw600dp)。

我们需要的是平板电脑(sw600dp),它具有以下实现:

<style name="Widget.Design.TabLayout" parent="Base.Widget.Design.TabLayout">
        <item name="tabGravity">center</item>
        <item name="tabMode">fixed</item>
 </style>

通过这种样式,我们将使用“ fill ”值使用“ tabGravity ”(可能的值为“ center”或“ fill”)。

但是我们需要更深入地研究,然后才能看到这一点从扩展而来Base.Widget.Design.TabLayout,该实现是:

<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
    <item name="tabMaxWidth">@dimen/tab_max_width</item>
    <item name="tabIndicatorColor">?attr/colorAccent</item>
    <item name="tabIndicatorHeight">2dp</item>
    <item name="tabPaddingStart">12dp</item>
    <item name="tabPaddingEnd">12dp</item>
    <item name="tabBackground">?attr/selectableItemBackground</item>
    <item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
    <item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>

因此,从这种样式中,我们将需要覆盖“ tabMaxWidth ”。就我而言,我将其设置为0dp,因此它没有限制。

我的风格如下所示:

<style name="MyTabLayout" parent="Widget.Design.TabLayout">
        <item name="tabGravity">fill</item>
        <item name="tabMaxWidth">0dp</item>
</style>

然后选项卡栏将左右填充整个屏幕。


1
很好的发现..扎根。但请在顶部突出显示确切的答案,这样会更容易找到不想阅读所有答案的人
Shirish Herwade '16

很棒的解决方案,怪异的api看起来像您可以控制它而无需更改基础样式。看起来tabMaxWidth是真正的罪魁祸首
kandroidj16年

3
这就像夏洛克的一集。谢谢!!
丽莎·雷

29

可滚动解决方案:(TabLayout.MODE_SCROLLABLE),也就是说,当您需要两个以上的选项卡(动态选项卡)时

步骤1:style.xml

<style name="tabCustomStyle" parent="Widget.Design.TabLayout">
            <item name="tabGravity">fill</item>
            <item name="tabMaxWidth">0dp</item>
            <item name="tabIndicatorColor">#FFFEEFC4</item>
            <item name="tabIndicatorHeight">2dp</item>
            <item name="tabTextAppearance">@style/MyCustomTabTextAppearance</item>
            <item name="tabSelectedTextColor">#FFFEEFC4</item>
        </style>

        <style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
            <item name="android:textSize">@dimen/tab_text_size</item>
            <item name="android:textAppearance">@style/TextAppearance.roboto_medium</item>
            <item name="textAllCaps">true</item>
        </style>
        <style name="TextAppearance.roboto_medium" parent="android:TextAppearance">
            <item name="android:fontFamily">sans-serif-medium</item>
        </style>

第2步:您的xml布局

<android.support.design.widget.TabLayout
            android:id="@+id/sliding_tabs"
            style="@style/tabCustomStyle"
            android:layout_width="match_parent"
            android:layout_height="@dimen/tab_strip_height"
            android:background="@color/your_color"
            app:tabMode="scrollable"
            app:tabTextColor="@color/your_color" />

步骤3:在您的“活动/片段”中,您可以使用任何选项卡。

/**
     * To allow equal width for each tab, while (TabLayout.MODE_SCROLLABLE)
     */
    private void allotEachTabWithEqualWidth() {

        ViewGroup slidingTabStrip = (ViewGroup) mTabLayout.getChildAt(0);
        for (int i = 0; i < mTabLayout.getTabCount(); i++) {
            View tab = slidingTabStrip.getChildAt(i);
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) tab.getLayoutParams();
            layoutParams.weight = 1;
            tab.setLayoutParams(layoutParams);
        }

    }

这仅适用于1个以上的标签,如果我们只有一个标签,则该标签不会填充标签布局。为了解决该问题,我添加了app:tabMaxWidth =“ 1000dp”,它可以正常工作。
jzeferino

这对我来说效果最好。在我的自定义选项卡布局类中,我覆盖addTab并设置了每个选项卡的权重。 override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
贾斯汀·李

15

要强制制表符占据整个宽度(分成相等的大小),请对TabLayout视图应用以下内容:

TabLayout tabLayout = (TabLayout) findViewById(R.id.your_tab_layout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);

2
只是让大家知道,如果您TabLayout将设置为app:tabMode=“scrollable”,这将不起作用,这将导致制表符变为固定长度(长字会自动换行),并且制表符将不再滑动,从而使制表符再次“固定”。
Sakiboy '17

5

这很有帮助,您必须尝试

 <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed"
        app:tabIndicatorColor="@color/white"
        app:tabSelectedTextColor="@color/white"
        app:tabTextColor="@color/orange" />

4
<android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMaxWidth="0dp"
            app:tabGravity="fill"
            app:tabMode="fixed" />

为我工作。这个也有xmlns:app="http://schemas.android.com/apk/res-auto"


3

对我来说,以下代码可以正常工作。

<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabGravity="fill"/>

2

检查以下代码以获取解决方案。

下面是布局代码:

<com.yourpackage.CustomTabLayout
    android:id="@+id/tabs"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/off_white"
    app:tabIndicatorColor="@color/primaryColor"
    app:tabIndicatorHeight="3dp"
    app:tabMode="scrollable"
    app:tabPaddingEnd="0dp"
    app:tabPaddingStart="0dp" />

注意,对于动态制表符计数,请不要忘记调用setTabNumbers(tabcount)。

import android.content.Context;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.util.
import java.lang.reflect.Field;

public class CustomTabLayout extends TabLayout
{
    private static final int WIDTH_INDEX = 0;
    private int DIVIDER_FACTOR = 3;
    private static final String SCROLLABLE_TAB_MIN_WIDTH = "mScrollableTabMinWidth";

    public CustomTabLayout(Context context) {
        super(context);
        initTabMinWidth();
    }

    public CustomTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initTabMinWidth();
    }

    public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initTabMinWidth();
    }

    public void setTabNumbers(int num)
    {
        this.DIVIDER_FACTOR = num;
        initTabMinWidth();
    }

    private void initTabMinWidth()
    {
        int[] wh = getScreenSize(getContext());
        int tabMinWidth = wh[WIDTH_INDEX] / DIVIDER_FACTOR;

        Log.v("CUSTOM TAB LAYOUT", "SCREEN WIDTH = " + wh[WIDTH_INDEX] + " && tabTotalWidth = " + (tabMinWidth*DIVIDER_FACTOR) + " && TotalTabs = " + DIVIDER_FACTOR);

        Field field;
        try {
            field = TabLayout.class.getDeclaredField(SCROLLABLE_TAB_MIN_WIDTH);
            field.setAccessible(true);
            field.set(this, tabMinWidth);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static final int WIDTH_INDEX = 0;
    private static final int HEIGHT_INDEX = 1;

    public static int[] getScreenSize(Context context) {
        int[] widthHeight = new int[2];
        widthHeight[WIDTH_INDEX] = 0;
        widthHeight[HEIGHT_INDEX] = 0;

        try {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();

            Point size = new Point();
            display.getSize(size);
            widthHeight[WIDTH_INDEX] = size.x;
            widthHeight[HEIGHT_INDEX] = size.y;

            if (!isScreenSizeRetrieved(widthHeight))
            {
                DisplayMetrics metrics = new DisplayMetrics();
                display.getMetrics(metrics);
                widthHeight[0] = metrics.widthPixels;
                widthHeight[1] = metrics.heightPixels;
            }

            // Last defense. Use deprecated API that was introduced in lower than API 13
            if (!isScreenSizeRetrieved(widthHeight)) {
                widthHeight[0] = display.getWidth(); // deprecated
                widthHeight[1] = display.getHeight(); // deprecated
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return widthHeight;
    }

    private static boolean isScreenSizeRetrieved(int[] widthHeight) {
        return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
    }
}

参考来自https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efe


2

Scrollable(Kotlin)解决方案

在xml中:

     <com.google.android.material.tabs.TabLayout
            android:id="@+id/home_tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMaxWidth="0dp"
            app:tabMode="scrollable"
            android:fillViewport="true"
            app:tabGravity="fill" />

在科特林:

就我而言,如果少于3个标签,我会分配相等的空间。

注意:如果条件符合您的要求

        if(list.size <= 3){
          allotEachTabWithEqualWidth(your_tab_layout)
        }

     fun allotEachTabWithEqualWidth(tabLayout: TabLayout) {
        mTabLayout.tabMode=  TabLayout.MODE_FIXED
        val slidingTabStrip = tabLayout.getChildAt(0) as ViewGroup
        for (i in 0 until tabLayout.getTabCount()) {
            val tab = slidingTabStrip.getChildAt(i)
            val layoutParams = tab.layoutParams as LinearLayout.LayoutParams
            layoutParams.weight = 1f
            tab.layoutParams = layoutParams
        }

    }

1

为什么要这么忙呢?只需将app:tabMode="scrollable"您的TabLayout放入XML中即可。而已。

在此处输入图片说明


1
如果有3个标签怎么办?这将不适合屏幕(分页是指从服务器API来动态)选项卡计数在运行时知道..
拉姆·普拉卡什铢

然后,您甚至可以像这样以编程方式tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);进行设置。这也只是为tabLayout设置的属性,而与添加静态或动态标签的数量无关。
阿里·阿克拉姆

它将根据文本大小调整标签宽度。用图像检查我编辑的答案。
阿里·阿克拉姆

在这种情况下,选项卡模式是可滚动的,那么最后您会看到空白的空间看起来很奇怪
Ram Prakash Bhat

1

在这个问题的变体中,我有3个中等大小的标签,这些标签没有占据平板电脑的整个宽度。我不需要选项卡在平板电脑上可滚动,因为平板电脑足够大,可以一起显示所有选项卡,而无需任何滚动。但是我确实需要这些选项卡在手机上可滚动,因为手机太小而无法同时显示所有选项卡。

对于我而言,最好的解决方案是添加一个res/layout-sw600dp/main_activity.xml文件,其中相关的TabLayout可以具有app:tabGravity="fill"app:tabMode="fixed"。但是在我的常规中res/layout/main_activity.xml,我省略了app:tabGravity="fill"app:tabMode="fixed"app:tabMode="scrollable"而是选择了。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.