【问题标题】:Tab not taking full width on Tablet device [Using android.support.design.widget.TabLayout]平板电脑设备上的选项卡未占据全宽 [使用 android.support.design.widget.TabLayout]
【发布时间】:2015-08-30 20:47:40
【问题描述】:

我将标签设置为 UPDATE 29/05/2015 this 帖子。在我的 Nexus 4 手机上,标签占据全宽,但在 nexus 7 平板电脑上,它位于中间,不覆盖全屏。

Nexus 7 屏幕截图 Nexus 4 截图

【问题讨论】:

  • 在完全相同的问题上苦苦挣扎了 6 个小时,但我没有意识到它只有标签有问题...想想在 stackoverflow 上应该有功能可以对一个问题进行 10 次投票...
  • 请尝试在问题中添加更多标签...(这样对像我这样的人更有帮助),因为我在谷歌搜索列表的第三页找到了这个问题

标签: android tabs width android-appcompat android-tablayout


【解决方案1】:

我遇到了同样的问题,我检查了 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>

从这种样式中,我们将使用“填充”值来使用“tabGravity”(可能的值是“中心”或“填充”)。

但是我们需要再深入一点,然后我们看到这个扩展自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>

然后标签栏会左右填满整个屏幕。

【讨论】:

  • 很好的发现.. 去根。但是请在顶部突出显示确切答案,这样会更容易找到不想阅读所有答案的人
  • 很棒的解决方案,奇怪的是 api 看起来你可以在不改变底层样式的情况下控制它。看起来 tabMaxWidth 是真正的罪魁祸首
  • 这就像夏洛克的一集。谢谢!!
【解决方案2】:

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

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

【讨论】:

  • 只是让人们知道,如果您的 TabLayout 设置为 app:tabMode=“scrollable”,这将不起作用,这将导致选项卡变为固定长度(长字将换行)并且选项卡不会更长的幻灯片,基本上使标签再次“固定”。
【解决方案3】:

“更简单”的答案 borrowed from Kaizie 只需在您的 TabLayout xml 中添加 app:tabMaxWidth="0dp":

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

【讨论】:

  • 如果我需要它可以滚动怎么办?更改 tabMode 以支持滚动会破坏此解决方案。
  • 任何可滚动的解决方案?
  • 嗨..我试过添加这个。但单个选项卡并没有占据选项卡布局的整个宽度。
  • 如果未设置 tabMode,此解决方案也有效。可滚动的 tapMode 似乎不支持填充重力和 0dp 最大宽度的功能。
  • 为什么会这样呢?这是默认行为吗?还是我没用好的东西?将选项卡设置在中间是否是指南的一部分?使用 3 个以上的标签时,我不会发生这种情况。仅适用于 2 个标签。
【解决方案4】:

对我来说,下面的代码已经足够了。

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

【讨论】:

    【解决方案5】:
    <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"

    【讨论】:

      【解决方案6】:

      可滚动的解决方案:(TabLayout.MODE_SCROLLABLE),即当您需要超过 2 个选项卡时(动态选项卡)

      第 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" 并且它起作用了。
      • 这对我来说效果最好。在我的自定义选项卡布局类中,我覆盖了addTab,并在添加每个选项卡时为其设置权重。 override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
      【解决方案7】:

      这很有帮助,你必须尝试

       <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" />
      

      【讨论】:

        【解决方案8】:

        为什么要忙着工作? 只需将app:tabMode="scrollable" 放在 XML 中的 TabLayout 中。 就是这样。

        【讨论】:

        • 如果有 3 个标签怎么办?不适合屏幕的(标签是动态的,来自服务器 API)标签计数在运行时已知..
        • 然后您甚至可以像这样以编程方式设置tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); 这只是为 tabLayout 设置的属性,无论您添加多少静态或动态选项卡。
        • 它将根据文本大小制作标签宽度。用图像检查我编辑的答案。
        • 是的,在这种情况下选项卡模式是可滚动的,那么最后你会看到看起来很奇怪的空白空间
        【解决方案9】:

        在我的这个问题的变体中,我有 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"。

        【讨论】:

          【解决方案10】:

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

          下面是布局代码:

          <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

          【讨论】:

            【解决方案11】:

            可滚动的解决方案 (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" />
            

            在 Kotlin 中:

            在我的情况下,如果少于 3 个选项卡,我会分配相等的空间。

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

                    if(list.size <= 3){
                      allotEachTabWithEqualWidth(your_tab_layout)
                    }
            
                 fun allotEachTabWithEqualWidth(tabLayout: TabLayout) {
                    tabLayout.tabMode=  TabLayout.MODE_SCROLLABLE
                    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
                    }
            
                }
            

            【讨论】:

              【解决方案12】:

              请注意,您还需要设置

                app:tabPaddingStart="-1dp"
                app:tabPaddingEnd="-1dp"
              

              填满所有空间

              【讨论】:

              【解决方案13】:

              刚刚做到了这一点,就像一个魅力

              <com.google.android.material.tabs.TabLayout
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  app:tabGravity="fill"
                  app:tabMaxWidth="0dp"/>
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-12-30
                • 1970-01-01
                • 1970-01-01
                • 2016-04-24
                • 1970-01-01
                相关资源
                最近更新 更多