Zakładka projektowania obsługi systemu Android: Centrum grawitacji i przewijanie trybu

101

Próbuję użyć nowego projektu TabLayout w moim projekcie. Chcę, aby układ dostosowywał się do każdego rozmiaru i orientacji ekranu, ale można go poprawnie zobaczyć w jednej orientacji.

Mam do czynienia z Gravity and Mode ustawiając mój tabLayout jako:

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

Więc spodziewam się, że jeśli nie ma miejsca, tabLayout jest przewijalne, ale jeśli jest miejsce, jest wyśrodkowane.

Z przewodników:

public static final int GRAVITY_CENTER Grawitacja używana do układania zakładek w środku TabLayout.

public static final int GRAVITY_FILL Grawitacja używana do wypełnienia TabLayout tak bardzo, jak to możliwe. Ta opcja działa tylko wtedy, gdy jest używana z MODE_FIXED.

public static final int MODE_FIXED Stałe karty wyświetlają wszystkie karty jednocześnie i najlepiej ich używać z zawartością korzystającą z szybkiego przełączania między kartami. Maksymalna liczba zakładek jest ograniczona przez szerokość widoku. Stałe zakładki mają równą szerokość w oparciu o najszerszą etykietę.

public static final int MODE_SCROLLABLE Przewijalne karty wyświetlają podzbiór zakładek w dowolnym momencie i mogą zawierać dłuższe etykiety i większą liczbę zakładek. Najlepiej nadają się do przeglądania kontekstów w interfejsach dotykowych, gdy użytkownicy nie muszą bezpośrednio porównywać etykiet kart.

Więc GRAVITY_FILL jest kompatybilny tylko z MODE_FIXED, ale co nie określa niczego dla GRAVITY_CENTER, spodziewam się, że będzie kompatybilny z MODE_SCROLLABLE, ale to właśnie otrzymuję, używając GRAVITY_CENTER i MODE_SCROLLABLE

wprowadź opis obrazu tutaj

Tak więc używa SCROLLABLE w obu orientacjach, ale nie używa GRAVITY_CENTER.

Tego właśnie oczekiwałbym od krajobrazu; ale żeby to mieć, muszę ustawić MODE_FIXED, więc w portrecie otrzymuję:

wprowadź opis obrazu tutaj

Dlaczego GRAVITY_CENTER nie działa dla SCROLLABLE, jeśli tabLayout pasuje do ekranu? Czy istnieje sposób, aby dynamicznie ustawić grawitację i tryb (i zobaczyć, czego się spodziewam)?

Dziękuję Ci bardzo!

EDITED: To jest układ mojego 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" />
Javier Delgado
źródło
@ Fighter42 znalazłeś jakieś rozwiązanie tego problemu? Mam ten sam problem.
Spynet
Jedynym sposobem, jaki znalazłem, było uzyskanie rozmiaru zakładek (ręcznie), a następnie dynamiczna konfiguracja parametrów układu w zależności od tego, czy pasuje, czy nie.
Javier Delgado
@ Fighter42, czy możesz opublikować przykładowy kod rozwiązania, którego używasz?
Sammys,
1
Wiem, że moja odpowiedź nie jest dobra dla logiki, ale pomaga mi. Umieść kilka spacji przed i po tekście. Wtedy będzie można go przewijać. w obu trybach.
AmmY

Odpowiedzi:

131

Efekty tylko grawitacji tabulatorów MODE_FIXED.

Możliwym rozwiązaniem jest ustawienie layout_widthsię wrap_contenti layout_gravitydo 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" />

Jeśli zakładki są mniejsze niż szerokość ekranu, to TabLayoutsamo będzie mniejsze i będzie wyśrodkowane z powodu grawitacji. Jeśli zakładki są większe niż szerokość ekranu, TabLayoutdopasują się do szerokości ekranu i aktywuje się przewijanie.

tachyonflux
źródło
1
Używam Material Design dla mojej aplikacji. Śledziłem próbkę z androidhive.info/2015/09/… Przewijana karta nie działa w urządzeniach KitKat i Jelly Bean. W Lollipop mogę przewijać kartę, ale w urządzeniach innych niż Lollipop przewijanie kart nie działa, ale przesuwanie działa dobrze. Czy mogę wiedzieć, jaki byłby problem.
user2681579
To nie zadziałało dla mnie w API 15 / support.design:25.1.0. Tabulatory były wyrównane, gdy były węższe niż szerokość okna. Ustawienie app:tabMaxWidth="0dp"i android:layout_centerHorizontal="true"praca w celu wyśrodkowania zakładek.
Baker
1
U mnie zadziałało. Karty są zawsze wyśrodkowane, ale jeśli w rzeczywistości nie można ich przewijać, nie wypełniają całej szerokości.
José Augustinho
15

tak to zrobiłem

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

Dokonałem niewielkich zmian w rozwiązaniu @Mario Velasco na części uruchamialnej

Strumień
źródło
To rozwiązanie ma te same problemy, o których wspomniałem przy rozwiązaniu Tiago.
Sotti
To rozwiązanie działa na karcie bez ikony, co jeśli mam ikonę z tekstem? : /
Emre Tekin
@EmreTekin tak, to działa z ikoną, moje zakładki miały ikony z tekstem
Flux
tabLayout.getWidth()zawsze zwraca dla mnie zero
ishandutta2007
8

Ponieważ nie znalazłem przyczyny takiego zachowania, użyłem następującego kodu:

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

Zasadniczo muszę ręcznie obliczyć szerokość mojego tabLayout, a następnie ustawiam tryb Tab w zależności od tego, czy tabLayout pasuje do urządzenia, czy nie.

Powodem, dla którego ręcznie otrzymuję rozmiar układu, jest to, że nie wszystkie karty mają tę samą szerokość w trybie przewijania, co może sprowokować, że niektóre nazwy używają 2 wierszy, jak mi się to zdarzyło w przykładzie.

Javier Delgado
źródło
Dzięki temu rozwiązaniu tekst mógłby zostać potencjalnie zmniejszony i zawierałby 2 wiersze. Zobacz inne odpowiedzi i rozwiązania w tym wątku na ten temat. Zmniejszasz ryzyko, że to się pojawi, ale i tak będzie się pojawiać często, gdy TabLayout jest trochę mniejszy niż screenWidth.
Sotti
8

sprawia, że ​​wszystko jest proste, wystarczy dodać aplikację: tabMode = "scrollable" i android: layout_gravity = "bottom"

takie jak to

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

wprowadź opis obrazu tutaj

Rajesh Kumar
źródło
7
Nie o to prosi twórca. Problem z tym podejściem polega na tym, że w scenariuszach, w których masz 2 karty lub 3 trzy karty w telefonach, w których tekst jest mały, będziesz mieć układ podobny do sklepu Google Play, w którym karty znajdują się po lewej stronie. Twórca chce, aby zakładki sięgały od krawędzi do krawędzi, gdy jest to możliwe, i przewijały w przeciwnym razie.
Sotti
Taki sam problem. Możesz to naprawić?
Hoang Duc Tuan
7

Spójrz na android-tablayouthelper

Automatycznie przełączaj TabLayout.MODE_FIXED i TabLayout.MODE_SCROLLABLE w zależności od całkowitej szerokości karty.

Derek Beattie
źródło
Ale kiedy tytuły zakładek są dynamiczne. Tekst trafia do następnego wiersza. A jeśli używasz niestandardowego układu dla karty. Tekst elipsy na końcu, jak
AndroidGeek
4

To jest rozwiązanie, którego użyłem do automatycznej zmiany między SCROLLABLEi FIXED+ FILL. To jest pełny kod rozwiązania @ Fighter42:

(Poniższy kod pokazuje, gdzie umieścić modyfikację, jeśli użyłeś szablonu działań Google z kartami)

@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);
            }
        }
    });
}

Układ:

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

Jeśli nie musisz wypełniać szerokości, lepiej użyj rozwiązania @karaokyo.

Mario Velasco
źródło
to działa dobrze; przełączanie się między orientacją poziomą a portretową robi dokładnie to, czego można się spodziewać. Google powinien zaimplementować to w domyślnym szablonie aktywności na kartach.
Someone Somewhere
Ta odpowiedź ma te same problemy, o których wspomniałem w rozwiązaniu Tiago.
Sotti
4

Aby to osiągnąć, stworzyłem klasę AdaptiveTabLayout. To był jedyny sposób, w jaki udało mi się rozwiązać problem, odpowiedzieć na pytanie i uniknąć / obejść problemy, których nie mają inne odpowiedzi.

Uwagi:

  • Obsługuje układy telefonów / tabletów.
  • Obsługuje przypadki, w których jest wystarczająco dużo miejsca, MODE_SCROLLABLEale za mało miejsca MODE_FIXED. Jeśli nie poradzisz sobie z tym przypadkiem, stanie się to na niektórych urządzeniach, zobaczysz różne rozmiary tekstu lub wypalisz dwie linie tekstu w niektórych zakładkach, co wygląda źle.
  • Ma rzeczywiste miary i nie przyjmuje żadnych założeń (jak ekran ma szerokość 360 dp lub cokolwiek ...). Działa to z rzeczywistymi rozmiarami ekranu i rzeczywistymi rozmiarami kart. Oznacza to, że działa dobrze z tłumaczeniami, ponieważ nie zakłada żadnego rozmiaru tabulatora, zakładki są mierzone.
  • Zajmuje się różnymi przepustkami w fazie onLayout, aby uniknąć dodatkowej pracy.
  • Szerokość układu musi znajdować wrap_contentsię w pliku xml. Nie ustawiaj żadnego trybu ani grawitacji w pliku XML.

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

}

A to jest klasa DeviceUtils:

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

}

Użyj przykładu:

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

Sens

Problemy / Poproś o pomoc:

  • Zobaczysz to:

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

Nie jestem pewien, jak to rozwiązać. Jakieś sugestie?

  • Aby wykonać miary potomne TabLayout, robię kilka rzutów i założeń (tak jak element potomny jest LinearLayout zawierającym inne widoki ...) Może to powodować problemy w dalszych aktualizacjach biblioteki Design Support Library. Lepsze podejście / sugestie?
Sotti
źródło
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"/>

user3205930
źródło
2

Bardzo prosty przykład i zawsze działa.

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

    });

}
LordTAO
źródło
Dzięki za pomysł. Z drobną zmianą w moim przypadku, działa jak urok
Eren Tüfekçi
1

To jedyny kod, który działał dla mnie:

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

DisplayMetrics można pobrać za pomocą tego:

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

Twój XML TabLayout powinien wyglądać tak (nie zapomnij ustawić tabMaxWidth na 0):

<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"/>
Tiago
źródło
1
To już prawie koniec, ale są pewne problemy. Najbardziej oczywistym problemem jest to, że na niektórych urządzeniach (i większości powolnych) faktycznie zobaczysz, jak układ jest modyfikowany i zmieniany.
Sotti
1
Jest inny problem, to podejście mierzy całkowitą szerokość TabLayout, aby zdecydować, czy ma być przewijalny, czy nie. To nie jest zbyt dokładne. Są sytuacje, w których TabLayout nie osiąga obu krawędzi w trybie przewijania, ale nie ma wystarczającej ilości miejsca na tryb stały bez zmniejszania tekstu nadużywania liczby linii na karcie (zwykle 2). Jest to bezpośrednia konsekwencja tego, że karty w trybie stałym mają stałą szerokość (screenWidth / numberOfTabs), podczas gdy w trybie przewijania zawijają tekst + dopełnienia.
Sotti
1

Wszystko, czego potrzebujesz, to dodać następujące elementy do swojego TabLayout

custom:tabGravity="fill"

Więc będziesz miał:

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"
        />
RicNjesh
źródło
Nie o to prosi twórca. Problem polega na tym, że zakładki nigdy nie będą przewijalne i pozbędziesz się miejsca na ekranie. Karty zaczną zmniejszać swój tekst i ostatecznie będą miały dwie linie.
Sotti
1

Rozwiązałem to za pomocą następujących

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

    }
zohaib khaliq
źródło
1

Moje ostateczne rozwiązanie

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
        }
    }
}
user4097210
źródło