Tablet cihazında tam genişlik almayan sekme [android.support.design.widget.TabLayout'u kullanma]


206

Bu yazı UPDATE 29/05/2015 olarak kurulum sekmeleri var . Sekmeler Nexus 4 cep telefonumda tam genişliğe sahip, ancak nexus 7 tabletinde ortada yer alıyor ve tam ekran genişliğini kapsamıyor.

Nexus 7 ekran görüntüsü Nexus7 Nexus 4 ekran görüntüsü Nexus 4


6 saat boyunca aynı sorunla mücadele ediyordu, ancak sadece sekmelerle ilgili bir sorun olduğunu fark etmedim ... stackoverflow üzerinde bir soruyu 10 kez yükseltmek için işlevsellik olması gerektiğini düşünün ...
Shirish Herwade

lütfen sorulara daha fazla etiket eklemeye çalışın ... (bu yüzden benim gibi insanlar için daha yararlı olacaktır), çünkü bu soru google arama
listemin

Yanıtlar:


600

Bir "basit" cevabı Kaizie ödünç sadece ekleyerek olurdu app:tabMaxWidth="0dp"senin içinde 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
Kaydırılabilir olması gerekirse ne olur? Kaydırma işlemini desteklemek için tabMode öğesini değiştirmek bu çözümü kırar.
Tiago

3
Kaydırılabilir için herhangi bir çözüm var mı?
sunlover3

5
Merhaba .. Bunu eklemeyi denedim. ancak tek sekme sekme düzeninin tüm genişliğini almıyor.
Surinder

3
Bu çözüm, tabMode ayarlanmamışsa da çalışır. Kaydırılabilir tapMode, doldurulmuş yerçekimi ve 0dp maksimum genişlik özelliklerini desteklemiyor gibi görünüyor.
Julio Mendoza

3
Neden oluyor? Varsayılan davranış bu mu? Yoksa iyi kullanmadığım bir şey mi? Sekmeleri ortaya koymak kılavuzların bir parçası mı? 3+ sekme kullanılırken bu benim için olmaz. Sadece 2 sekme için.
android geliştirici

92

Aynı sorunu vardı ve TabLayout stilini kontrol ettim ve varsayılan stilinin Widget.Design.TabLayoutfarklı uygulamalara (normal, manzara ve sw600dp) sahip olduğunu gördüm.

İhtiyacımız olan, aşağıdaki uygulamaya sahip tabletler (sw600dp) için:

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

Bu stilde , "dolgu" değeri kullanılarak " tabGravity " (olası değerler "orta" veya "dolgu") kullanılır.

Ancak daha derine inmemiz gerekiyor ve sonra bunun bunun Base.Widget.Design.TabLayouthangi uygulamadan oluştuğunu görüyoruz :

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

Bu nedenle, bu stilde " tabMaxWidth " i geçersiz kılmamız gerekecek . Benim durumumda bunu ayarladım 0dp, bu yüzden sınırı yok.

Ve tarzım şöyle görünüyordu:

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

Ardından sekme çubuğu tüm ekranı bir yandan diğer yana dolduracaktır.


1
güzel keşif .. köküne gidiyor. Ama lütfen üstteki cevabı vurgulayın, tüm cevabı okumak istemeyen birini bulmak daha kolay olacaktır
Shirish Herwade

harika bir çözüm, altta yatan stili değiştirmeden kontrol edebilmeniz için api'nin nasıl göründüğü garip. TabMaxWidth gerçek suçlu gibi görünüyor
kandroidj

3
Bu Sherlock'un bir bölümü gibi. Teşekkür ederim!!
Lisa Wray

29

Kaydırılabilir çözüm: (TabLayout.MODE_SCROLLABLE), yani 2'den fazla sekmeye ihtiyacınız olduğunda (Dinamik sekmeler)

1.Adım: 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>

2. Adım: XML düzeniniz

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

3. Adım: Etkinlik / Parçanızda sekmelerin olduğu yerlerde.

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

    }

Bu yalnızca 1'den fazla sekme ile çalıştı, yalnızca bir sekmemiz varsa sekme sekme düzenini doldurmaz. Bu sorunu çözmek için app ekledim: tabMaxWidth = "1000dp" ve işe yaradı.
jzeferino

Bu benim için en iyisi oldu. Özel sekme düzeni sınıfımda, addTabher sekmenin ağırlığını eklendikçe geçersiz kıldım ve ayarladım. override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
Justin Lee

15

Sekmeleri tam genişliği almaya (eşit boyutlara bölünmüş) zorlamak için TabLayoutgörünüme aşağıdakileri uygulayın :

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

2
Sadece insanlara haber vermek, eğer TabLayoutayarlanmışsa bu işe yaramazsa app:tabMode=“scrollable”, sekmelerin sabit uzunluğuna (uzun kelimeler sarılır) neden olur ve sekmeler artık kaymaz ve sekmeleri tekrar "sabit" hale getirir.
Sakiboy

5

Bu denemelisin

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

benim için çalış. Bu da varxmlns:app="http://schemas.android.com/apk/res-auto"


3

Benim için aşağıdaki kod çalıştı ve yeterliydi.

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

2

Çözümler için aşağıdaki kodu kontrol edin.

Düzen kodu aşağıdadır:

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

Dinamik sekme sayımı için setTabNumbers (tabcount) öğesini aramayı unutmayın.

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

Https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efe adresinden alınan referans


2

Kaydırılabilir Çözüm (Kotlin)

Xml dilinde:

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

Kotlin'de:

Benim durumumda 3'ten az sekme varsa eşit alan ayırıyorum.

Not: eğer şartının şartının

        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

Neden bütün bu telaşlı işler? Sadece koymak app:tabMode="scrollable"XML halinde TabLayout içinde. Bu kadar.

resim açıklamasını buraya girin


1
3 sekme varsa ne olur? ekrana sığmayan (sekmeler sunucu API'sinden gelen dinamik) sekmeler çalışma zamanında bilinir ..
Ram Prakash Bhat

O zaman bu şekilde programsal olarak da ayarlayabilirsiniz. tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);Ayrıca bu, tabLayout için ayarlanacak bir özelliktir ve bu, kaç sekme statik veya dinamik eklediğiniz önemli değildir.
Ali Akram

Metin boyutuna göre sekme genişliği yapar. Düzenlenmiş cevabımı görüntü ile kontrol et.
Ali Akram

Ya bu durumda sekme modu KAYDIRILABİLİR sonra sonunda u garip görünecek boş alan göreceksiniz
Ram Prakash Bhat

1

Bu sorunun varyantında, tabletlerde tam genişliğe sahip olmayan 3 adet orta boy sekme vardı. Tabletlerde sekmeleri bir arada görüntülemeye yetecek kadar büyük olduğundan sekmelerin tabletlerde kaydırılabilir olması gerekmiyordu. Ancak, telefonların tüm sekmeleri birlikte görüntüleyemeyecek kadar küçük olması nedeniyle sekmelerin telefonlarda kaydırılabilir olması gerekiyordu.

Benim durumumdaki en iyi çözüm res/layout-sw600dp/main_activity.xml, ilgili TabLayout'un sahip olabileceği bir dosya eklemekti app:tabGravity="fill"ve app:tabMode="fixed". Ama regular res/layout/main_activity.xml, dışarı bıraktı app:tabGravity="fill"ve app:tabMode="fixed"ve vardı app:tabMode="scrollable"yerine.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.