Вкладка не приймає повну ширину на пристрої планшетного ПК [Використання android.support.design.widget.TabLayout]


202

У мене є вкладки , настройки , як UPDATE 29/05/2015 цей пост. Вкладки займають повну ширину на моєму мобільному пристрої Nexus 4, але на планшеті Nexus 7 - у центрі, а не на повній ширині екрана.

Скріншот Nexus 7 Скріншот Nexus7 Nexus 4 Nexus 4


6 годин боровся з точно такою ж проблемою, але я не усвідомлював, що у неї є проблеми лише з вкладками ... думаю, на stackoverflow має бути функціональність, щоб відповісти на питання 10 разів ...
Shirish Herwade

будь ласка, спробуйте додати більше тегів до питань ... (так буде кориснішим людям, як я), тому що це питання я знайшов на третій сторінці мого списку пошуку в Google
Shirish Herwade

Відповіді:


595

" Простішу " відповідь, запозичену у 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 для підтримки прокрутки порушує це рішення.
Тіаго

3
Будь-яке рішення для прокрутки?
sunlover3

5
Привіт .. Я спробував додати це. але одна вкладка не займає всієї ширини макета вкладки.
Рахул

3
Це рішення також працює, якщо tabMode не встановлений. Прокручується tapMode не підтримує функції заповненої сили тяжіння та максимальної ширини 0dp.
Хуліо Мендоса

3
Чому це відбувається, хоча? Це поведінка за замовчуванням? Або щось я не використовував добре? Це частина вказівок щодо встановлення вкладок посередині? Це не трапляється для мене під час використання 3+ вкладок. Тільки на 2 вкладки.
андроїд розробник

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>

З цього стилю ми будемо використовувати " tabGravity " (можливі значення яких є "центр" або "заповнити"), використовуючи значення "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

чудове рішення, дивно, як виглядає api, ви можете керувати ним, не змінюючи основний стиль. Схоже, tabMaxWidth є справжнім винуватцем
kandroidj

3
Це як епізод Шерлока. Дякую!!
Ліза Урай

29

Рішення для прокрутки: (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 вкладкою, якщо у нас є лише одна вкладка, вона не заповнює макет вкладки. Щоб вирішити цю проблему, я додав додаток: 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”, це призведе до того, що вкладки стануть фіксованою довжиною (довгі слова перегортатимуться), і вкладки більше не будуть ковзати, фактично зробивши вкладки «зафіксованими» знову.
Сакібой

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 (рахунок рахунків).

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-programmatic-8146d6101efe


2

Рішення для прокрутки (Котлін)

У 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. Ніколи не важливо, скільки вкладок ви додаєте статичні чи динамічні.
Алі Акрам

Він зробить ширину вкладки відповідно до розміру тексту. Перевірте мою відредаговану відповідь із зображенням.
Алі Акрам

Так, у такому випадку вкладка "РЕКЛАМНИЙ", тоді в кінці ви побачите порожній простір, який виглядає дивно
Рам Пракаш Бхат

1

У моєму варіанті цієї проблеми у мене було 3 вкладки середнього розміру, які не займали повну ширину планшетів. Мені не потрібно було вкладки прокручувати на планшетах, оскільки планшети досить великі, щоб відображати вкладки всі разом без прокрутки. Але мені потрібні були вкладки для прокрутки на телефонах, оскільки телефони занадто малі, щоб відображати всі вкладки разом.

Найкращим рішенням у моєму випадку було додати res/layout-sw600dp/main_activity.xmlфайл, де міг би бути app:tabGravity="fill"і відповідний TabLayout app:tabMode="fixed". Але в своєму звичайному res/layout/main_activity.xml, я вийшов з app:tabGravity="fill"і app:tabMode="fixed", і мав app:tabMode="scrollable"замість цього.


-1

Зверніть увагу, що вам також потрібно встановити

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

щоб заповнити весь простір


Ласкаво просимо до переповнення стека. Будь ласка, вирушайте на екскурсію . Це сайт із запитаннями та відповідями, а не дискусійний форум. Цей розділ призначений лише для повних відповідей. Як тільки ви наберете 50 балів репутації, запитуючи та відповідаючи, ви зможете коментувати питання та відповіді інших користувачів .
Кріс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.