web-dev-qa-db-fra.com

TabLayout ne remplit pas la largeur lorsque tabMode est défini sur 'scrollable'

J'ai ajouté TabLayout (de la bibliothèque de support v22.2.1) à mon fragment en tant que:

<Android.support.design.widget.TabLayout
        Android:id="@+id/tabs"
        style="@style/MyColorAccentTabLayout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:tabMode="scrollable"/>

Le problème est que lorsque l'orientation du fragment est paysage (avant ou après la création initiale du fragment), la variable TabLayout ne correspond pas à la largeur de la variable Fragment (oui, la largeur du parent a également la valeur match_parent).

Lorsque la largeur de l’écran est petite (c’est-à-dire que tous les onglets ne peuvent pas être affichés en même temps):  enter image description here

Lorsque la largeur de l'écran est suffisante pour afficher tous les onglets (voir l'espace vide à droite):  enter image description here

Si je change tabMode en fixe, la largeur est remplie mais les onglets sont trop petits. Existe-t-il une solution appropriée?

39
Sufian

Je suppose que c'est la manière la plus simple de réaliser ce que vous voulez.

public class CustomTabLayout extends TabLayout {
    public CustomTabLayout(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        try {
            if (getTabCount() == 0)
                return;
            Field field = TabLayout.class.getDeclaredField("mTabMinWidth");
            field.setAccessible(true);
            field.set(this, (int) (getMeasuredWidth() / (float) getTabCount()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
16
dtx12

Au lieu de créer TabLayout personnalisé et de modifier ou de créer des mises en page qui agissent comme des enveloppes autour de TabLayout uniquement pour l'arrière-plan. Essaye ça,

<Android.support.design.widget.TabLayout
    Android:id="@+id/tabs"
    style="@style/MyColorAccentTabLayout"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    <!-- Instead of setting app:tabBackground -->
    Android:background="@color/colorAccent"
    app:tabGravity="fill"
    app:tabMode="scrollable"/>

Cela définira l'arrière-plan derrière tabLayout au lieu de l'arrière-plan derrière chaque onglet.

26
Rohit

Essayez celui-ci, c’est une solution de contournement qui définit tabMaxWidth="0dp", tabGravity="fill" et tabMode="fixed".

 <Android.support.v4.view.ViewPager
     Android:id="@+id/container"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent"
     app:layout_behavior="@string/appbar_scrolling_view_behavior">
     <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"/>
</Android.support.v4.view.ViewPager>

Capture d'écran sur une tablette 10 pouces:

 screenshot

15
Chandler

essayez avec ces changements 

 <Android.support.design.widget.TabLayout
        Android:id="@+id/sliding_tabs"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill" />
1
rKrishna

s'il vous plaît utilisez ce qu'il va résoudre ce problème définitivement

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

Je me débattais aussi et la plupart des options ci-dessus ne fonctionnaient pas pour moi. J'ai donc créé une version sur la réponse du DTX12.

J'ai un booléen pour vérifier la tablette ou pas et faire une vérification sur le paysage et le portrait. Puis définissez la mise en page en fonction du nombre d'onglets.

Vous devrez peut-être rendre la méthode publique et l'appeler lors d'une rotation/configurationchange.

Dans le code CustomTabLayout, j'ai remplacé la méthode mintabswidth

private void initTabMinWidth()
{



    boolean isTablet = getContext().getResources().getBoolean(R.bool.device_is_tablet);
    boolean isLandscape = (wh[WIDTH_INDEX] > wh[HEIGHT_INDEX]) ? true : false;


    if (isTablet)
    {
        if (isLandscape)
        {
            if (this.getTabCount() > 8)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        } else
        {
            if (this.getTabCount() > 6)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        }
    } else
    {
        if (isLandscape)
        {
            if (this.getTabCount() > 6)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        } else
        {
            if (this.getTabCount() > 4)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        }
    }


}
0
renevdkooi

Vous pouvez utiliser app: tabMaxWidth = "0dp" dans tablayout

0
Rahul Gupta

faites-le simplement de cette façon et ajoutez app:tabMaxWidth="0dp" et utilisez également app:tabGravity="fill"

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