La pestaña no ocupa todo el ancho en el dispositivo Tablet [Uso de android.support.design.widget.TabLayout]

203

He configurado pestañas como ACTUALIZACIÓN 29/05/2015 esta publicación. Las pestañas ocupan todo el ancho de mi móvil Nexus 4, pero en la tableta nexus 7 lo colocan en el centro y no cubren el ancho de la pantalla completa.

Captura de pantalla de Nexus 7 Captura de pantalla de Nexus7 Nexus 4 Nexus 4

Max
fuente
estuvo luchando con exactamente el mismo problema durante 6 horas, pero no me di cuenta de que solo tiene problemas con las pestañas ... piense en stackoverflow debería haber funcionalidad para votar 10 veces una pregunta ...
Shirish Herwade
intente agregar más etiquetas a las preguntas ... (por lo que será más útil para personas como yo), porque esta pregunta la encontré en la tercera página de mi lista de búsqueda de Google
Shirish Herwade

Respuestas:

596

Una respuesta "más simple" prestada de Kaizie sería agregar app:tabMaxWidth="0dp"en su 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" />
Adam Johns
fuente
19
¿Qué pasa si necesito que sea desplazable? Cambiar tabMode para soportar el desplazamiento rompe esta solución.
Tiago
3
¿Alguna solución para desplazable?
sunlover3
55
Hola .. He intentado agregar esto. pero la pestaña única no ocupa todo el ancho del diseño de la pestaña.
Surinder
3
Esta solución también funciona si no se establece tabMode. El tapMode desplazable no parece admitir las características de gravedad llena y ancho máximo de 0dp.
Julio Mendoza
3
¿Por qué ocurre sin embargo? ¿Es el comportamiento predeterminado? ¿O algo que no usé bien? ¿Forma parte de las directrices establecer las pestañas en el medio? Esto no ocurre para mí cuando utilizo más de 3 pestañas. Solo para 2 pestañas.
Desarrollador de Android
92

Tuve el mismo problema y verifiqué el estilo TabLayout, y descubrí que su estilo predeterminado es el Widget.Design.TabLayoutque tiene implementaciones diferentes (normal, horizontal y sw600dp).

El que necesitamos es el de las tabletas (sw600dp) que tiene la siguiente implementación:

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

De este estilo usaremos " tabGravity " (cuyos valores posibles son "centro" o "relleno") usando el valor "relleno".

Pero tenemos que ir más profundo, y luego vemos que este se extiende Base.Widget.Design.TabLayout, cuya implementación es:

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

Entonces, a partir de este estilo, tendremos que anular " tabMaxWidth ". En mi caso, lo configuré para 0dpque no tenga límite.

Y mi estilo se veía así:

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

Y luego la barra de pestañas llenará toda la pantalla de lado a lado.

Kaizie
fuente
1
Buen descubrimiento ... yendo a la raíz. Pero resalte la respuesta exacta en la parte superior, será más fácil encontrar a alguien que no quiera leer toda la respuesta
Shirish Herwade
Gran solución, extraño cómo se ve la API, puede controlarla sin cambiar el estilo subyacente. Parece que tabMaxWidth es el verdadero culpable
kandroidj
3
Esto es como un episodio de Sherlock. ¡¡Gracias!!
Lisa Wray
29

Solución para desplazamiento: (TabLayout.MODE_SCROLLABLE), es decir, cuando necesite más de 2 pestañas (pestañas dinámicas)

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

Paso 2: tu diseño 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" />

Paso 3: en tu Actividad / Fragmento donde sea que tengas pestañas.

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

    }
Ram Prakash Bhat
fuente
Esto funcionó solo con más de 1 pestaña, si solo tenemos una pestaña, la pestaña no llena el diseño de la pestaña. Para resolver ese problema, agregué la aplicación: tabMaxWidth = "1000dp" y funcionó.
jzeferino
Esto funcionó mejor para mí. En mi clase de diseño de pestaña personalizada, anulé addTaby configuré el peso de cada pestaña a medida que se agregaba. override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
Justin Lee
15

Para obligar a las pestañas a ocupar todo el ancho (divididas en tamaños iguales), aplique lo siguiente a la TabLayoutvista:

TabLayout tabLayout = (TabLayout) findViewById(R.id.your_tab_layout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
Jon Cairns
fuente
2
Solo para que la gente sepa, esto no funciona si TabLayoutestá configurado en app:tabMode=“scrollable”, dará como resultado que las pestañas tengan una longitud fija (las palabras largas se ajustarán) y las pestañas ya no se deslizarán, esencialmente haciendo que las pestañas se "arreglen" nuevamente.
Sakiboy el
5

Esto es útil, debes intentarlo

 <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" />
Ness Tyagi
fuente
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" />

trabaja para mi. Esto también tienexmlns:app="http://schemas.android.com/apk/res-auto"

Cam Hùng Huỳnh
fuente
3

Para mí, el siguiente código funcionó y fue suficiente.

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

Verifique el código a continuación para encontrar soluciones.

A continuación se muestra el código de diseño:

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

Tenga en cuenta que para el recuento dinámico de pestañas, no olvide llamar a 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;
    }
}

Referencia tomada de https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatic-8146d6101efe

Kuldeep Sakhiya
fuente
2

Solución para desplazable (Kotlin)

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

En Kotlin:

En mi caso, si tengo menos de 3 pestañas, asigno el mismo espacio.

Nota: Si la condición es según su requisito

        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
        }

    }
Ranjith Kumar
fuente
1

¿Por qué todo ese trabajo agitado? Simplemente ponga app:tabMode="scrollable"su TabLayout en XML. Eso es.

ingrese la descripción de la imagen aquí

Ali Akram
fuente
1
¿Qué pasa si hay 3 pestañas? eso no encaja en la pantalla (las pestañas son dinámicas que provienen de la API del servidor) recuento de pestañas conocido en tiempo de ejecución ..
Ram Prakash Bhat
Luego, incluso puede establecer mediante programación de esta manera. tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);Además, esta es solo una propiedad para establecer para tabLayout, sin importar cuántas pestañas esté agregando estática o dinámica.
Ali Akram
Hará el ancho de la pestaña de acuerdo con el tamaño del texto. Verifique mi respuesta editada con la imagen.
Ali Akram
Ya en ese caso, el modo de pestaña es DESPLAZABLE y al final verá un espacio vacío que parece extraño
Ram Prakash Bhat
1

En mi variante de este problema, tenía 3 pestañas de tamaño moderado que no ocupaban todo el ancho en las tabletas. No necesitaba que las pestañas fueran desplazables en tabletas, ya que las tabletas son lo suficientemente grandes como para mostrar las pestañas juntas sin ningún desplazamiento. Pero sí necesitaba que las pestañas fueran desplazables en los teléfonos, ya que los teléfonos son demasiado pequeños para mostrar todas las pestañas juntas.

La mejor solución en mi caso fue agregar un res/layout-sw600dp/main_activity.xmlarchivo, donde el TabLayout relevante podría tener app:tabGravity="fill"y app:tabMode="fixed". Pero en mi habitual res/layout/main_activity.xml, me salí app:tabGravity="fill"y app:tabMode="fixed", y en su app:tabMode="scrollable"lugar.

CKP78
fuente
-1

Tenga en cuenta que también debe configurar

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

para llenar todo el espacio

Andrew Barabash
fuente
Bienvenido a Stack Overflow. Por favor toma el tour . Este es un sitio de preguntas y respuestas, no un foro de discusión. Esta sección es solo para respuestas completas. Una vez que haya obtenido 50 puntos de reputación al preguntar y responder, podrá comentar las preguntas y respuestas de otros usuarios .
Chris