Tab tidak mengambil lebar penuh pada perangkat Tablet [Menggunakan android.support.design.widget.TabLayout]

203

Saya memiliki tab pengaturan sebagai PEMBARUAN 29/05/2015 pos ini . Tab mengambil lebar penuh pada ponsel Nexus 4 saya tetapi pada tablet nexus 7 berada di tengah dan tidak menutupi lebar layar penuh.

Tangkapan layar Nexus 7 tangkapan layar Nexus 7 Nexus 4 Nexus 4

Maks
sumber
sedang berjuang dengan masalah yang sama persis selama 6 jam, tapi saya tidak menyadari itu memiliki masalah dengan tab saja ... berpikir pada stackoverflow harus ada fungsi untuk menjawab pertanyaan 10 kali ...
Shirish Herwade
tolong coba tambahkan lebih banyak tag ke pertanyaan ... (jadi akan lebih bermanfaat bagi orang-orang seperti saya), karena pertanyaan ini saya temukan di halaman ketiga daftar pencarian google saya
Shirish Herwade

Jawaban:

596

Jawaban "sederhana" yang dipinjam dari Kaizie hanya akan ditambahkan app:tabMaxWidth="0dp"di TabLayoutxml Anda :

<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
sumber
19
Bagaimana jika saya harus dapat digulir? Mengubah tabMode untuk mendukung gulir memecah solusi ini.
Tiago
3
Ada solusi untuk digulir?
sunlover3
5
Hai .. Saya sudah mencoba menambahkan ini. tetapi satu tab tidak mengambil seluruh lebar tata letak tab.
Surinder
3
Solusi ini juga berfungsi jika tabMode tidak disetel. TapMode yang dapat digulir tidak muncul untuk mendukung fitur gravitasi penuh dan lebar 0dp maks.
Julio Mendoza
3
Mengapa itu terjadi? Apakah ini perilaku default? Atau sesuatu yang tidak saya gunakan dengan baik? Apakah ini merupakan bagian dari pedoman untuk mengatur tab di tengah? Ini tidak terjadi pada saya saat menggunakan 3+ tab. Hanya untuk 2 tab.
pengembang android
92

Saya memiliki masalah yang sama dan saya memeriksa gaya TabLayout, dan saya menemukan bahwa gaya standarnya adalah Widget.Design.TabLayout yang memiliki implementasi yang berbeda (normal, landscape, dan sw600dp).

Yang kami butuhkan adalah yang untuk tablet (sw600dp) yang memiliki implementasi sebagai berikut:

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

Dari style ini kita akan menggunakan " tabGravity " (yang nilainya mungkin "center" atau "fill") menggunakan nilai "fill".

Tetapi kita perlu melangkah lebih dalam, dan kemudian kita melihat bahwa yang ini meluas Base.Widget.Design.TabLayout, yang implementasinya adalah:

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

Jadi, dari gaya ini kita perlu mengganti " tabMaxWidth ". Dalam kasus saya, saya mengaturnya 0dp, sehingga tidak memiliki batas.

Dan gaya saya terlihat seperti ini:

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

Dan kemudian bilah tab akan mengisi seluruh layar dari sisi ke sisi.

Kaizie
sumber
1
Penemuan yang bagus .. pergi ke root. Tapi tolong sorot jawaban yang tepat di atas, akan lebih mudah untuk menemukan seseorang yang tidak ingin membaca semua jawabannya
Shirish Herwade
solusi hebat, aneh bagaimana api terlihat seperti Anda bisa mengendalikannya tanpa mengubah gaya yang mendasarinya. Sepertinya tabMaxWidth adalah pelakunya yang sebenarnya
kandroidj
3
Ini seperti sebuah episode Sherlock. Terima kasih!!
Lisa Wray
29

Solusi untuk digulir: (TabLayout.MODE_SCROLLABLE), saat itulah Anda membutuhkan lebih dari 2 tab (tab Dinamis)

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

Langkah 2: Tata letak xml Anda

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

Langkah 3: Di Aktivitas / Fragmen Anda di mana saja Anda memiliki tab.

/**
     * 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
sumber
Ini hanya berfungsi dengan lebih dari 1 tab, jika kita hanya memiliki satu tab, tab tersebut tidak memenuhi tata letak tab. Untuk mengatasi masalah itu saya menambahkan aplikasi: tabMaxWidth = "1000dp" dan berhasil.
jzeferino
Ini bekerja paling baik untuk saya. Di kelas tata letak tab kustom saya, saya mengesampingkan addTabdan mengatur berat untuk setiap tab seperti yang ditambahkan. override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
Justin Lee
15

Untuk memaksa tab mengambil lebar penuh (dibagi menjadi ukuran yang sama), terapkan yang berikut ini pada TabLayouttampilan:

TabLayout tabLayout = (TabLayout) findViewById(R.id.your_tab_layout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
Jon Cairns
sumber
2
Hanya dengan memberi tahu orang-orang, ini tidak berfungsi jika Anda TabLayoutdiatur ke app:tabMode=“scrollable”, itu akan menghasilkan tab menjadi panjang tetap (kata-kata panjang akan membungkus) dan tab tidak akan lagi meluncur, pada dasarnya membuat tab "diperbaiki" lagi.
Sakiboy
5

Ini membantu Anda harus mencoba

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

bekerja untukku. Ini juga punyaxmlns:app="http://schemas.android.com/apk/res-auto"

Cam Hùng Huỳnh
sumber
3

Bagi saya kode berikut ini berfungsi dan cukup.

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

Periksa kode di bawah ini untuk solusinya.

Di bawah ini adalah kode tata letak:

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

Catatan, untuk jumlah tab dinamis, jangan lupa untuk memanggil 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;
    }
}

Referensi diambil dari https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efe

Kuldeep Sakhiya
sumber
2

Solusi untuk Digulirkan (Kotlin)

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

Di Kotlin:

Dalam kasus saya jika kurang dari 3 tab saya mengalokasikan ruang yang sama.

Catatan: Jika kondisinya sesuai kebutuhan Anda

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

Kenapa semua pekerjaan itu sibuk? Cukup masukkan app:tabMode="scrollable"TabLayout Anda dalam XML. Itu dia.

masukkan deskripsi gambar di sini

Ali Akram
sumber
1
Bagaimana jika ada 3 tab? yang tidak cocok dengan layar (tab bersifat dinamis yang berasal dari server API) tab dihitung saat dijalankan ..
Ram Prakash Bhat
Kemudian Anda bahkan dapat mengatur secara terprogram seperti ini tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);Juga ini hanya properti untuk diatur ke tabLayout ini tidak masalah berapa banyak tab yang Anda tambahkan statis atau dinamis.
Ali Akram
Ini akan membuat lebar tab sesuai dengan ukuran teks. Periksa jawaban saya yang diedit dengan gambar.
Ali Akram
Ya dalam hal ini tab mode SCROLLABLE maka pada akhirnya kamu akan melihat ruang kosong yang terlihat aneh
Ram Prakash Bhat
1

Dalam varian saya tentang masalah ini, saya memiliki 3 tab ukuran sedang yang tidak terlalu lebar pada tablet. Saya tidak perlu tab untuk dapat digulir di tablet, karena tablet cukup besar untuk menampilkan semua tab tanpa digulir. Tetapi saya memang membutuhkan tab yang dapat digulir pada ponsel, karena ponsel terlalu kecil untuk menampilkan semua tab secara bersamaan.

Solusi terbaik dalam kasus saya adalah menambahkan res/layout-sw600dp/main_activity.xmlfile, di mana TabLayout yang relevan dapat memiliki app:tabGravity="fill"dan app:tabMode="fixed". Tetapi dalam rutinitas saya res/layout/main_activity.xml, saya keluar app:tabGravity="fill"dan app:tabMode="fixed", dan app:tabMode="scrollable"sebaliknya.

CKP78
sumber
-1

Harap dicatat bahwa Anda juga perlu mengatur

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

untuk mengisi semua ruang

Andrew Barabash
sumber
Selamat datang di Stack Overflow. Silakan ikuti tur . Ini adalah situs tanya jawab, bukan forum diskusi. Bagian ini hanya untuk jawaban lengkap. Setelah Anda mendapatkan 50 poin reputasi dengan bertanya dan menjawab, Anda akan dapat mengomentari pertanyaan dan jawaban pengguna lain .
Chris