タブレットデバイスでタブが全幅にならない[android.support.design.widget.TabLayoutを使用]


203

私はこの投稿を2015年5月29日更新 として設定タブを持っています。Nexus 4モバイルではタブが全幅になりますが、Nexus 7タブレットでは中央に配置され、画面の全幅をカバーしません。

Nexus 7スクリーンショット ネクサス7 Nexus 4スクリーンショット ネクサス4


まったく同じ問題に6時間苦労していましたが、タブにのみ問題があることに気づきませんでした... stackoverflowで質問を10回
賛成する

質問にタグを追加してみてください...(私のような人にとってはもっと役立つでしょう)。この質問は、グーグル検索リストの3番目のページ
Shirish Herwade

回答:


596

Kaizieから借用した「より単純な」答えapp:tabMaxWidth="0dp"は、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
スクロール可能にする必要がある場合はどうなりますか?スクロールをサポートするようにtabModeを変更すると、このソリューションが機能しなくなります。
ティアゴ2016年

3
スクロール可能な解決策はありますか?
sunlover3 2016年

5
こんにちは。これを追加してみました。ただし、単一のタブはタブレイアウトの幅全体を占めていません。
Surinder 2016年

3
このソリューションは、tabModeが設定されていない場合にも機能します。スクロール可能なtapModeは、重力の充填と最大幅0dpの機能をサポートしていないようです。
フリオメンドーサ

3
なぜそれが起こるのですか?これはデフォルトの動作ですか?または私がうまく利用しなかった何か?中央にタブを設定することはガイドラインの一部ですか?3つ以上のタブを使用している場合、これは発生しません。2つのタブのみ。
Android開発者

91

同じ問題が発生し、TabLayoutスタイルを確認したところ、デフォルトスタイルはWidget.Design.TabLayout実装が異なる(通常、横長、sw600dp)ことがわかりました。

必要なのは、次の実装を持つタブレット用のもの(sw600dp)です。

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

このスタイルから、「fill」の値を使用して「tabGravity」(可能な値は「center」または「fill」)を使用します。

しかし、さらに深く掘り下げる必要があります。するとBase.Widget.Design.TabLayout、これはからの拡張であることがわかります。

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

したがって、このスタイルから「tabMaxWidth」をオーバーライドする必要があります。私の場合はに設定した0dpので、制限はありません。

そして、私のスタイルは次のようになりました:

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

そして、タブバーは画面全体を左右に埋めます。


1
いい発見だね。しかし、一番上の正確な答えを強調表示してください。すべての答えを読みたくない人を見つける方が簡単になります
Shirish Herwade

優れたソリューション。APIがどのように見えるかがおかしいので、基になるスタイルを変更せずにAPIを制御できます。tabMaxWidthが本当の原因であるようです
kandroidj

3
これはシャーロックのエピソードのようなものです。ありがとうございました!!
リサ・レー

29

スクロール可能なソリューション:(TabLayout.MODE_SCROLLABLE)、つまり、2つ以上のタブ(動的タブ)が必要になったとき

ステップ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>

ステップ2:XMLレイアウト

<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:タブがあるアクティビティ/フラグメント。

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

    }

これは、複数のタブでのみ機能しました。タブが1つしかない場合、タブはタブレイアウトを満たしません。この問題を解決するために、app:tabMaxWidth = "1000dp"を追加しました。
jzeferino 2016年

これは私にとって最も効果的でした。私のカスタムタブレイアウトクラスaddTabでは、追加された各タブの重みをオーバーライドして設定しました。 override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
ジャスティンリー

15

タブが全幅を占めるようにする(等しいサイズに分割する)には、TabLayoutビューに以下を適用します。

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

2
をにTabLayout設定するとapp:tabMode=“scrollable”、これはに設定されている場合は機能しません。タブが固定長になり(長い単語は折り返されます)、タブがスライドしなくなり、基本的にタブが再び「固定」されます。
Sakiboy 2017

5

これはあなたが試さなければならないのに役立ちます

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

私のために働きます。これも持っていますxmlns:app="http://schemas.android.com/apk/res-auto"


3

私にとっては、次のコードが機能し、十分でした。

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

2

以下のコードで解決策を確認してください。

以下はレイアウトコードです:

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

動的なタブ数については、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;
    }
}

https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efeからの参照


2

スクロール可能なソリューション(Kotlin)

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

コトリンでは:

私の場合、タブが3つ未満の場合は、等しいスペースを割り当てます。

注:条件が要件に従っている場合

        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

なぜそんなに忙しい仕事なのか?app:tabMode="scrollable"TabLayoutをXMLに入れるだけです。それでおしまい。

ここに画像の説明を入力してください


1
3つのタブがある場合はどうなりますか?画面に収まらないことを(タブは、サーバAPIから来ている動的なもの)タブは、実行時に知られてカウント...
ラムプラカシュBhatさん

次に、このようにプログラムで設定することもできます。tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);これは、静的または動的に追加するタブの数に関係なく、tabLayoutに設定するプロパティです。
Ali Akram

テキストのサイズに応じてタブの幅を作成します。編集した回答を画像で確認してください。
Ali Akram

その場合、タブモードはスクロール可能です。最後に、奇妙に見える空のスペースが表示されます
Ram Prakash Bhat

1

この問題の変種では、中程度のサイズの3つのタブがあり、タブレットで全幅を使用していませんでした。タブレットはスクロールせずにすべてのタブを一緒に表示できる大きさなので、タブレットでタブをスクロール可能にする必要はありませんでした。しかし、電話はすべてのタブを一緒に表示するには小さすぎるため、電話でタブをスクロール可能にする必要がありました。

私の場合は最善の解決策を追加することでしたres/layout-sw600dp/main_activity.xml関連TabLayoutを持つことができたファイルを、app:tabGravity="fill"app:tabMode="fixed"。しかし、私の常連ではres/layout/main_activity.xml、私は外に出app:tabGravity="fill"app:tabMode="fixed"、そしてapp:tabMode="scrollable"代わりに持っていました。


-1

また、設定する必要があることに注意してください

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

すべてのスペースを埋める


Stack Overflowへようこそ。ツアーに参加してください。これは質疑応答サイトであり、ディスカッションフォーラムではありません。このセクションは完全な回答のみを対象としています。質問と回答によって50の評判ポイントを獲得すると、他のユーザーの質問と回答コメントできるようになります
クリス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.