Android Support Design TabLayout: Schwerkraftzentrum und Modus scrollbar


98

Ich versuche, das neue Design TabLayout in meinem Projekt zu verwenden. Ich möchte, dass sich das Layout an jede Bildschirmgröße und Ausrichtung anpasst, aber es kann in einer Ausrichtung korrekt angezeigt werden.

Ich habe es mit Schwerkraft und Modus zu tun, indem ich mein tabLayout wie folgt einstelle:

    tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

Ich gehe davon aus, dass das tabLayout scrollbar ist, wenn kein Platz vorhanden ist. Wenn jedoch Platz vorhanden ist, wird es zentriert.

Aus den Guides:

public static final int GRAVITY_CENTER Schwerkraft, mit der die Registerkarten in der Mitte des TabLayouts angeordnet werden.

public static final int GRAVITY_FILL Die Schwerkraft wird verwendet, um das TabLayout so weit wie möglich zu füllen. Diese Option wird nur wirksam, wenn sie mit MODE_FIXED verwendet wird.

public static final int MODE_FIXED Feste Registerkarten zeigen alle Registerkarten gleichzeitig an und werden am besten mit Inhalten verwendet, die von schnellen Pivots zwischen Registerkarten profitieren. Die maximale Anzahl von Registerkarten ist durch die Breite der Ansicht begrenzt. Feste Registerkarten haben die gleiche Breite, basierend auf der breitesten Registerkartenbezeichnung.

public static final int MODE_SCROLLABLE Bildlaufbare Registerkarten zeigen zu jedem Zeitpunkt eine Teilmenge von Registerkarten an und können längere Registerkartenbezeichnungen und eine größere Anzahl von Registerkarten enthalten. Sie eignen sich am besten zum Durchsuchen von Kontexten in Touch-Oberflächen, wenn Benutzer die Registerkartenbezeichnungen nicht direkt vergleichen müssen.

GRAVITY_FILL ist also nur mit MODE_FIXED kompatibel, aber da für GRAVITY_CENTER nichts angegeben ist, erwarte ich, dass es mit MODE_SCROLLABLE kompatibel ist, aber das bekomme ich mit GRAVITY_CENTER und MODE_SCROLLABLE

Geben Sie hier die Bildbeschreibung ein

Es wird also SCROLLABLE in beiden Ausrichtungen verwendet, jedoch nicht GRAVITY_CENTER.

Das würde ich für die Landschaft erwarten; Aber um dies zu haben, muss ich MODE_FIXED setzen, also bekomme ich im Hochformat:

Geben Sie hier die Bildbeschreibung ein

Warum funktioniert GRAVITY_CENTER nicht für SCROLLABLE, wenn das tabLayout zum Bildschirm passt? Gibt es eine Möglichkeit, die Schwerkraft und den Modus dynamisch einzustellen (und zu sehen, was ich erwarte)?

Vielen Dank!

BEARBEITET: Dies ist das Layout meines TabLayout:

<android.support.design.widget.TabLayout
    android:id="@+id/sliding_tabs"
    android:layout_width="match_parent"
    android:background="@color/orange_pager"
    android:layout_height="wrap_content" />

@ Fighter42 hast du eine Lösung dafür gefunden? Ich stehe vor dem gleichen Problem.
Spynet

Die einzige Möglichkeit, die ich gefunden habe, bestand darin, die Größe Ihrer Registerkarten (manuell) zu ermitteln und dann die Layoutparameter dynamisch zu konfigurieren, je nachdem, ob sie passen oder nicht.
Javier Delgado

@ Fighter42, können Sie einen Beispielcode für die von Ihnen verwendete Lösung veröffentlichen?
Sammys

1
Ich weiß, dass meine Antwort nicht gut für logisch ist, aber sie hilft mir. Setzen Sie einige Leerzeichen vor und nach dem Text. Dann wird es scrollbar sein. in beiden Modi.
AmmY

Antworten:


127

Tab Schwerkraft wirkt sich nur aus MODE_FIXED.

Eine mögliche Lösung ist Ihr gesetzt layout_widthzu wrap_contentund layout_gravityzu center_horizontal:

<android.support.design.widget.TabLayout
    android:id="@+id/sliding_tabs"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    app:tabMode="scrollable" />

Wenn die Registerkarten kleiner als die Bildschirmbreite sind, ist auch die TabLayoutselbst kleiner und wird aufgrund der Schwerkraft zentriert. Wenn die Registerkarten größer als die Bildschirmbreite sind, entspricht dies TabLayoutder Bildschirmbreite und das Scrollen wird aktiviert.


1
Ich verwende Material Design für meine App. Ich habe das Beispiel von androidhive.info/2015/09/ verfolgt. Tab scrollable funktioniert nicht in Kitkat- und Jelly Bean-Geräten. In Lollipop kann ich Tabs scrollen, aber in anderen als Lollipop-Geräten funktioniert Tab Scrollable nicht, aber Swipe funktioniert einwandfrei. Darf ich wissen, was das Problem wäre.
user2681579

Dies funktionierte bei API 15 / support.design:25.1.0 nicht. Tabulatoren wurden gerechtfertigt gelassen, wenn sie schmaler als die Fensterbreite waren. Einstellen app:tabMaxWidth="0dp"und android:layout_centerHorizontal="true"Arbeiten zum Zentrieren von Registerkarten.
Baker

1
Es hat bei mir funktioniert. Registerkarten sind immer zentriert, aber wenn sie nicht scrollbar sind, füllen sie nicht die gesamte Breite aus.
José Augustinho

14

So habe ich es gemacht

TabLayout.xml

<android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:background="@android:color/transparent"
            app:tabGravity="fill"
            app:tabMode="scrollable"
            app:tabTextAppearance="@style/TextAppearance.Design.Tab"
            app:tabSelectedTextColor="@color/myPrimaryColor"
            app:tabIndicatorColor="@color/myPrimaryColor"
            android:overScrollMode="never"
            />

Oncreate

@Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
        mTabLayout = (TabLayout)findViewById(R.id.tab_layout);
        mTabLayout.setOnTabSelectedListener(this);
        setSupportActionBar(mToolbar);

        mTabLayout.addTab(mTabLayout.newTab().setText("Dashboard"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Signature"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Booking/Sampling"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Calendar"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Customer Detail"));

        mTabLayout.post(mTabLayout_config);
    }

    Runnable mTabLayout_config = new Runnable()
    {
        @Override
        public void run()
        {

           if(mTabLayout.getWidth() < MainActivity.this.getResources().getDisplayMetrics().widthPixels)
            {
                mTabLayout.setTabMode(TabLayout.MODE_FIXED);
                ViewGroup.LayoutParams mParams = mTabLayout.getLayoutParams();
                mParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
                mTabLayout.setLayoutParams(mParams);

            }
            else
            {
                mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }
        }
    };

Ich habe kleine Änderungen an der Lösung von @Mario Velasco am ausführbaren Teil vorgenommen


Diese Lösung hat die gleichen Probleme, die ich bei der Lösung des Tiago erwähnt habe.
Sotti

Diese Lösung funktioniert auf einer Registerkarte ohne Symbol. Was ist, wenn ich ein Symbol mit Text habe? : /
Emre Tekin

@ EmreTekin ja es funktioniert mit einem Symbol, meine Registerkarten hatten Symbole mit Text
Flux

tabLayout.getWidth()gibt für mich immer null zurück
ishandutta2007

9

hält die Dinge einfach einfach App hinzufügen: tabMode = "scrollbar" und android: layout_gravity = "bottom"

genau wie dieser

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:tabMode="scrollable"
app:tabIndicatorColor="@color/colorAccent" />

Geben Sie hier die Bildbeschreibung ein


7
Dies ist nicht das, wonach der Schöpfer fragt. Das Problem bei diesem Ansatz besteht darin, dass in Szenarien mit zwei oder drei Registerkarten in Telefonen mit kleinem Text ein Layout wie im Google Play Store angezeigt wird, in dem sich die Registerkarten auf der linken Seite befinden. Der Ersteller möchte, dass die Registerkarten von Kante zu Kante reichen, wenn dies möglich ist, und ansonsten scrollen.
Sotti

Gleiches Problem. Du kannst es reparieren?
Hoang Duc Tuan

8

Da ich nicht herausgefunden habe, warum dieses Verhalten auftritt, habe ich den folgenden Code verwendet:

float myTabLayoutSize = 360;
if (DeviceInfo.getWidthDP(this) >= myTabLayoutSize ){
    tabLayout.setTabMode(TabLayout.MODE_FIXED);
} else {
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
}

Grundsätzlich muss ich die Breite meines tabLayout manuell berechnen und dann den Tab-Modus einstellen, je nachdem, ob das tabLayout in das Gerät passt oder nicht.

Der Grund, warum ich die Größe des Layouts manuell erhalte, ist, dass nicht alle Registerkarten im scrollbaren Modus dieselbe Breite haben. Dies könnte dazu führen, dass einige Namen zwei Zeilen verwenden, wie es mir im Beispiel passiert ist.


Mit dieser Lösung könnte der Text möglicherweise verkleinert werden und auch 2 Zeilen verwenden. Weitere Antworten und Lösungen finden Sie in diesem Thread. Sie verringern das Risiko, dass dies auftritt, werden jedoch trotzdem häufig angezeigt, wenn das TabLayout etwas kleiner als die Bildschirmbreite ist.
Sotti

7

Schauen Sie sich Android-Tablayouthelper

Das automatische Wechseln von TabLayout.MODE_FIXED und TabLayout.MODE_SCROLLABLE hängt von der Gesamtbreite der Registerkarten ab.


Aber wenn Tab-Titel dynamisch sind. Der Text geht in die nächste Zeile. Und wenn Sie ein benutzerdefiniertes Layout für die Registerkarte verwenden. Text Ellipsengröße am Ende wie
Zar E Ahmer

4

Dies ist die Lösung, mit der ich automatisch zwischen SCROLLABLEund FIXED+ gewechselt habe FILL. Dies ist der vollständige Code für die @ Fighter42-Lösung:

(Der folgende Code zeigt, wo die Änderung vorgenommen werden muss, wenn Sie die Aktivitätsvorlage mit Registerkarten von Google verwendet haben.)

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    // Set up the tabs
    final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

    // Mario Velasco's code
    tabLayout.post(new Runnable()
    {
        @Override
        public void run()
        {
            int tabLayoutWidth = tabLayout.getWidth();

            DisplayMetrics metrics = new DisplayMetrics();
            ActivityMain.this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int deviceWidth = metrics.widthPixels;

            if (tabLayoutWidth < deviceWidth)
            {
                tabLayout.setTabMode(TabLayout.MODE_FIXED);
                tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
            } else
            {
                tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }
        }
    });
}

Layout:

    <android.support.design.widget.TabLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

Wenn Sie die Breite nicht füllen müssen, verwenden Sie besser die @ karaokyo-Lösung.


das funktioniert gut; Das Umschalten zwischen Quer- und Hochformat macht genau das, was Sie erwarten. Google sollte dies in der Standardvorlage für Aktivitäten mit Registerkarten implementieren.
Jemand irgendwo

Diese Antwort hat die gleichen Probleme, die ich in der Lösung des Tiago erwähnt habe.
Sotti

4

Ich habe eine AdaptiveTabLayout-Klasse erstellt, um dies zu erreichen. Dies war die einzige Möglichkeit, das Problem tatsächlich zu lösen, die Frage zu beantworten und Probleme zu vermeiden / zu umgehen, die andere Antworten hier nicht haben.

Anmerkungen:

  • Verarbeitet Telefon- / Tablet-Layouts.
  • Behandelt Fälle, in denen genügend Platz, MODE_SCROLLABLEaber nicht genug Platz vorhanden ist MODE_FIXED. Wenn Sie diesen Fall nicht behandeln, werden auf einigen Geräten unterschiedliche Textgrößen angezeigt, oder es werden zwei Textzeilen in einigen Registerkarten angezeigt, was schlecht aussieht.
  • Es erhält echte Maßnahmen und macht keine Annahmen (wie der Bildschirm ist 360dp breit oder was auch immer ...). Dies funktioniert mit echten Bildschirmgrößen und echten Registerkartengrößen. Dies bedeutet, dass es gut mit Übersetzungen funktioniert, da keine Registerkartengröße angenommen wird und die Registerkarten gemessen werden.
  • Behandelt die verschiedenen Durchgänge in der onLayout-Phase, um zusätzliche Arbeit zu vermeiden.
  • Die Layoutbreite muss in wrap_contentder XML-Datei angegeben werden. Stellen Sie keinen Modus oder keine Schwerkraft für die XML ein.

AdaptiveTabLayout.java

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class AdaptiveTabLayout extends TabLayout
{
    private boolean mGravityAndModeSeUpNeeded = true;

    public AdaptiveTabLayout(@NonNull final Context context)
    {
        this(context, null);
    }

    public AdaptiveTabLayout(@NonNull final Context context, @Nullable final AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public AdaptiveTabLayout
    (
            @NonNull final Context context,
            @Nullable final AttributeSet attrs,
            final int defStyleAttr
    )
    {
        super(context, attrs, defStyleAttr);
        setTabMode(MODE_SCROLLABLE);
    }

    @Override
    protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b)
    {
        super.onLayout(changed, l, t, r, b);

        if (mGravityAndModeSeUpNeeded)
        {
            setModeAndGravity();
        }
    }

    private void setModeAndGravity()
    {
        final int tabCount = getTabCount();
        final int screenWidth = UtilsDevice.getScreenWidth();
        final int minWidthNeedForMixedMode = getMinSpaceNeededForFixedMode(tabCount);

        if (minWidthNeedForMixedMode == 0)
        {
            return;
        }
        else if (minWidthNeedForMixedMode < screenWidth)
        {
            setTabMode(MODE_FIXED);
            setTabGravity(UtilsDevice.isBigTablet() ? GRAVITY_CENTER : GRAVITY_FILL) ;
        }
        else
        {
            setTabMode(TabLayout.MODE_SCROLLABLE);
        }

        setLayoutParams(new LinearLayout.LayoutParams
                (LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

        mGravityAndModeSeUpNeeded = false;
    }

    private int getMinSpaceNeededForFixedMode(final int tabCount)
    {
        final LinearLayout linearLayout = (LinearLayout) getChildAt(0);
        int widestTab = 0;
        int currentWidth;

        for (int i = 0; i < tabCount; i++)
        {
            currentWidth = linearLayout.getChildAt(i).getWidth();

            if (currentWidth == 0) return 0;

            if (currentWidth > widestTab)
            {
                widestTab = currentWidth;
            }
        }

        return widestTab * tabCount;
    }

}

Und das ist die DeviceUtils-Klasse:

import android.content.res.Resources;

public class UtilsDevice extends Utils
{
    private static final int sWIDTH_FOR_BIG_TABLET_IN_DP = 720;

    private UtilsDevice() {}

    public static int pixelToDp(final int pixels)
    {
        return (int) (pixels / Resources.getSystem().getDisplayMetrics().density);
    }

    public static int getScreenWidth()
    {
        return Resources
                .getSystem()
                .getDisplayMetrics()
                .widthPixels;
    }

    public static boolean isBigTablet()
    {
        return pixelToDp(getScreenWidth()) >= sWIDTH_FOR_BIG_TABLET_IN_DP;
    }

}

Anwendungsbeispiel:

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.com.stackoverflow.example.AdaptiveTabLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="?colorPrimary"
        app:tabIndicatorColor="@color/white"
        app:tabSelectedTextColor="@color/text_white_primary"
        app:tabTextColor="@color/text_white_secondary"
        tools:layout_width="match_parent"/>

</FrameLayout>

Kern

Probleme / Um Hilfe bitten:

  • Du wirst das sehen:

Logcat:

W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$SlidingTabStrip{3e1ebcd6 V.ED.... ......ID 0,0-466,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{3423cb57 VFE...C. ..S...ID 0,0-144,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{377c4644 VFE...C. ......ID 144,0-322,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{19ead32d VFE...C. ......ID 322,0-466,96} during layout: running second layout pass

Ich bin nicht sicher, wie ich es lösen soll. Irgendwelche Vorschläge?

  • Um die untergeordneten TabLayout-Maßnahmen durchzuführen, mache ich einige Änderungen und Annahmen (wie das untergeordnete Element ein LinearLayout, das andere Ansichten enthält ...). Dies kann zu Problemen bei weiteren Aktualisierungen der Design Support Library führen. Ein besserer Ansatz / Vorschläge?

4
 <android.support.design.widget.TabLayout
                    android:id="@+id/tabList"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    app:tabMode="scrollable"/>

1

Dies ist der einzige Code, der für mich funktioniert hat:

public static void adjustTabLayoutBounds(final TabLayout tabLayout,
                                         final DisplayMetrics displayMetrics){

    final ViewTreeObserver vto = tabLayout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {

            tabLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            int totalTabPaddingPlusWidth = 0;
            for(int i=0; i < tabLayout.getTabCount(); i++){

                final LinearLayout tabView = ((LinearLayout)((LinearLayout) tabLayout.getChildAt(0)).getChildAt(i));
                totalTabPaddingPlusWidth += (tabView.getMeasuredWidth() + tabView.getPaddingLeft() + tabView.getPaddingRight());
            }

            if (totalTabPaddingPlusWidth <= displayMetrics.widthPixels){

                tabLayout.setTabMode(TabLayout.MODE_FIXED);
                tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

            }else{
                tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }

            tabLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        }
    });
}

Die DisplayMetrics können folgendermaßen abgerufen werden:

public DisplayMetrics getDisplayMetrics() {

    final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    final Display display = wm.getDefaultDisplay();
    final DisplayMetrics displayMetrics = new DisplayMetrics();

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        display.getMetrics(displayMetrics);

    }else{
        display.getRealMetrics(displayMetrics);
    }

    return displayMetrics;
}

Und Ihr TabLayout-XML sollte so aussehen (vergessen Sie nicht, tabMaxWidth auf 0 zu setzen):

<android.support.design.widget.TabLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tab_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:tabMaxWidth="0dp"/>

1
Dies ist fast da, aber es gibt einige Probleme. Das offensichtlichste Problem ist, dass Sie bei einigen Geräten (und den meisten langsamen) tatsächlich sehen, wie das Layout geändert und geändert wird.
Sotti

1
Es gibt ein weiteres Problem: Dieser Ansatz misst die Gesamtbreite des TabLayout, um zu entscheiden, ob ein Bildlauf durchgeführt werden soll oder nicht. Das ist nicht sehr genau. Es gibt Situationen, in denen das TabLayout im scrollbaren Modus nicht beide Kanten erreicht, aber für den festen Modus nicht genügend Platz vorhanden ist, ohne den Text zu verkleinern, wenn die Anzahl der Zeilen auf der Registerkarte missbraucht wird (normalerweise 2). Dies ist eine direkte Folge davon, dass die Registerkarten im festen Modus eine feste Breite (screenWidth / numberOfTabs) haben, während sie im scrollbaren Modus den Text + die Auffüllungen umbrechen.
Sotti

1

Sie müssen lediglich Folgendes zu Ihrem TabLayout hinzufügen

custom:tabGravity="fill"

Dann haben Sie:

xmlns:custom="http://schemas.android.com/apk/res-auto"
<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        custom:tabGravity="fill"
        />

Dies ist nicht das, wonach der Schöpfer fragt. Das Problem hierbei ist, dass die Registerkarten niemals scrollbar sind und Sie keinen Platz mehr auf dem Bildschirm haben. Die Registerkarten verkleinern den Text und werden schließlich zweizeilig.
Sotti

1

Ich habe das mit folgendem gelöst

if(tabLayout_chemistCategory.getTabCount()<4)
    {
        tabLayout_chemistCategory.setTabGravity(TabLayout.GRAVITY_FILL);
    }else
    {
        tabLayout_chemistCategory.setTabMode(TabLayout.MODE_SCROLLABLE);

    }

1

Sehr einfaches Beispiel und es funktioniert immer.

/**
 * Setup stretch and scrollable TabLayout.
 * The TabLayout initial parameters in layout must be:
 * android:layout_width="wrap_content"
 * app:tabMaxWidth="0dp"
 * app:tabGravity="fill"
 * app:tabMode="fixed"
 *
 * @param context   your Context
 * @param tabLayout your TabLayout
 */
public static void setupStretchTabLayout(Context context, TabLayout tabLayout) {
    tabLayout.post(() -> {

        ViewGroup.LayoutParams params = tabLayout.getLayoutParams();
        if (params.width == ViewGroup.LayoutParams.MATCH_PARENT) { // is already set up for stretch
            return;
        }

        int deviceWidth = context.getResources()
                                 .getDisplayMetrics().widthPixels;

        if (tabLayout.getWidth() < deviceWidth) {
            tabLayout.setTabMode(TabLayout.MODE_FIXED);
            params.width = ViewGroup.LayoutParams.MATCH_PARENT;
        } else {
            tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
        }
        tabLayout.setLayoutParams(params);

    });

}

Danke für die Idee. Mit ein wenig Abwechslung für meinen Fall funktioniert wie Charme
Eren Tüfekçi

1

Meine endgültige Lösung

class DynamicModeTabLayout : TabLayout {

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun setupWithViewPager(viewPager: ViewPager?) {
        super.setupWithViewPager(viewPager)

        val view = getChildAt(0) ?: return
        view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
        val size = view.measuredWidth

        if (size > measuredWidth) {
            tabMode = MODE_SCROLLABLE
            tabGravity = GRAVITY_CENTER
        } else {
            tabMode = MODE_FIXED
            tabGravity = GRAVITY_FILL
        }
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.