A guia não ocupa largura total no dispositivo Tablet [Usando android.support.design.widget.TabLayout]


203

Tenho guias de instalação como ATUALIZAÇÃO 29/05/2015 nesta postagem. As guias têm largura total no meu celular Nexus 4, mas no tablet do nexus 7 ele fica no centro e não cobre a largura da tela inteira.

Captura de tela do Nexus7 Nexus 7 Nexus 4


estava lutando com exatamente o mesmo problema para 6 horas, mas eu não sabia que ele tem problema apenas com abas ... pense em stackoverflow deve haver funcionalidade para upvote uma pergunta 10 vezes ...
— Shirish Herwade

por favor, tente adicionar mais tags a perguntas ... (por isso vai ser mais útil para pessoas como eu), porque esta pergunta eu encontrei na terceira página da minha lista de busca Google
— Shirish Herwade

Respostas:


596

Uma resposta "mais simples" emprestada do Kaizie estaria apenas adicionando app:tabMaxWidth="0dp"no seu 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
E se eu precisar que seja rolável? Alterar tabMode para oferecer suporte à rolagem quebra esta solução.
— Tiago

3
Alguma solução para rolagem?
— sunlover3

5
Oi .. Eu tentei adicionar isso. mas a guia única não ocupa toda a largura do layout da guia.
— Surinder

3
Esta solução também funciona se o tabMode não estiver definido. O tapMode rolável não parece suportar os recursos de gravidade preenchida e largura máxima de 0dp.
— Julio Mendoza

3
Por que isso ocorre? É o comportamento padrão? Ou algo que não usei bem? Faz parte das diretrizes definir as guias no meio? Isso não ocorre para mim ao usar 3 ou mais guias. Apenas para 2 abas.
— desenvolvedor android

92

Eu tive o mesmo problema e verifiquei o estilo TabLayout, e descobri que seu estilo padrão é o de Widget.Design.TabLayoutimplementações diferentes (normal, paisagem e sw600dp).

O que precisamos é o de tablets (sw600dp), que possui a seguinte implementação:

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

Nesse estilo, usaremos " tabGravity " (cujos valores possíveis são "centro" ou "preenchimento") usando o valor "preenchimento".

Mas precisamos ir mais fundo e, em seguida, vemos que este se estende de Base.Widget.Design.TabLayoutqual implementação é:

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

Portanto, a partir deste estilo, precisaremos substituir " tabMaxWidth ". No meu caso, defino-o para 0dpque ele não tenha limites.

E meu estilo ficou assim:

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

E então a barra de guias preencherá a tela inteira de um lado para o outro.


1
boa descoberta .. indo para a raiz. Mas, por favor destacar a resposta exata no topo, será mais fácil encontrar alguém que não quer ler toda a resposta
— Shirish Herwade

ótima solução, estranho como a API parece, você pode controlá-la sem alterar o estilo subjacente. Looks como tabMaxWidth é o verdadeiro culpado
— kandroidj

3
É como um episódio de Sherlock. Obrigado!!
— Lisa Wray

29

Solução para rolagem: (TabLayout.MODE_SCROLLABLE), ou seja, sempre que você precisar de mais de 2 guias (guias dinâmicas)

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

Etapa 2: seu layout 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" />

Etapa 3: em sua Atividade / Fragmento, sempre que houver guias.

/**
     * 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);
        }

    }

Isso funcionou apenas com mais de uma guia, se tivermos apenas uma guia, a guia não preencherá o layout da guia. Para resolver esse problema, adicionei app: tabMaxWidth = "1000dp" e funcionou.
— jzeferino

Isso funcionou melhor para mim. Na minha classe de layout de guia personalizada, substituí addTabe defino o peso de cada guia conforme ela foi adicionada. override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
— Justin Lee

15

Para forçar as guias a ocuparem toda a largura (divididas em tamanhos iguais), aplique o seguinte à TabLayoutexibição:

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

2
Apenas informando às pessoas que isso não funciona se o seu TabLayoutestiver definido app:tabMode=“scrollable”, resultará no comprimento fixo das guias (as palavras longas serão quebradas) e as guias não serão mais deslizadas, essencialmente tornando as guias "fixas" novamente.
— Sakiboy 24/08/19

5

Isso é útil, você deve tentar

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

trabalhe para mim. Isso também temxmlns:app="http://schemas.android.com/apk/res-auto"


3

Para mim, o código a seguir funcionou e foi suficiente.

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

2

Verifique o código abaixo para soluções.

Abaixo está o código do layout:

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

Observe que, para a contagem dinâmica de guias, não se esqueça de chamar 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;
    }
}

Referência retirada de https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efe


2

Solução para Scrollable (Kotlin)

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

Em Kotlin:

No meu caso, se menos de 3 guias alocarem espaço igual.

Nota: Se a condição é conforme sua exigência

        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

Por que todo esse trabalho agitado? Basta colocar o app:tabMode="scrollable"seu TabLayout em XML. É isso aí.

insira a descrição da imagem aqui


1
E se houver 3 abas? que não cabe à tela (guias são dinâmicas que estão vindo de API servidor) guias contagem conhecido em tempo de execução ..
— Ram Prakash Bhat

Em seguida, você pode definir programaticamente como este tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);Também é apenas uma propriedade a ser definida para tabLayout, não importa quantas guias você esteja adicionando, estática ou dinâmica.
— Ali Akram

Ele fará a largura da guia de acordo com o tamanho do texto. Verifique minha resposta editada com a imagem.
— Ali Akram

Ya em que o modo de guia caso é SCROLLABLE então no final u vai ver isso é espaço vazio parecer estranho
— Ram Prakash Bhat

1

Na minha variante desse problema, eu tinha três guias de tamanho moderado que não estavam ocupando toda a largura dos tablets. Eu não precisava que as guias fossem roláveis ​​nos tablets, pois os tablets são grandes o suficiente para exibir as guias juntas sem necessidade de rolagem. Mas eu precisava que as guias fossem roláveis ​​nos telefones, pois os telefones são pequenos demais para exibir todas as guias juntas.

A melhor solução no meu caso foi adicionar um res/layout-sw600dp/main_activity.xmlarquivo, onde o TabLayout relevante poderia ter app:tabGravity="fill"e app:tabMode="fixed". Mas no meu regular res/layout/main_activity.xml, eu deixei de fora app:tabGravity="fill"e app:tabMode="fixed", em app:tabMode="scrollable"vez disso.


-1

Observe que você também precisa definir

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

para preencher todo o espaço


Bem-vindo ao Stack Overflow. Por favor, faça o passeio . Este é um site de perguntas e respostas, não um fórum de discussão. Esta seção é apenas para respostas completas. Depois de ganhar 50 pontos de reputação, perguntando e respondendo, você poderá comentar as perguntas e respostas de outros usuários .
— Chris
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.