web-dev-qa-db-ja.com

tabModeが 'scrollable'に設定されているときにTabLayoutが幅を埋めない

フラグメントにTabLayout(サポートライブラリv22.2.1から)を次のように追加しました。

<Android.support.design.widget.TabLayout
        Android:id="@+id/tabs"
        style="@style/MyColorAccentTabLayout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:tabMode="scrollable"/>

問題は、フラグメントの向きが横向きの場合(フラグメントの最初の作成の前後)、TabLayoutFragmentの幅と一致しないことです(はい、親には幅があります)に設定 match_parent 同じように)。

画面の幅が小さい場合(つまり、すべてのタブを同時に表示できるわけではありません): enter image description here

画面の幅がすべてのタブを表示するのに十分な大きさの場合(右側の空白を参照): enter image description here

tabModeをfixedに変更すると、幅は塗りつぶされますが、タブが小さすぎます。適切な解決策はありますか?

41
Sufian

これがあなたが望むものを達成する最も簡単な方法だと思います。

public class CustomTabLayout extends TabLayout {
    public CustomTabLayout(Context context) {
        super(context);
    }

    public CustomTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        try {
            if (getTabCount() == 0)
                return;
            Field field = TabLayout.class.getDeclaredField("mTabMinWidth");
            field.setAccessible(true);
            field.set(this, (int) (getMeasuredWidth() / (float) getTabCount()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
16
dtx12

カスタムのTabLayoutを作成して、ハックしたり、背景のみのTabLayoutのラッパーとして機能するレイアウトを作成したりする代わりに。これを試して、

<Android.support.design.widget.TabLayout
    Android:id="@+id/tabs"
    style="@style/MyColorAccentTabLayout"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    <!-- Instead of setting app:tabBackground -->
    Android:background="@color/colorAccent"
    app:tabGravity="fill"
    app:tabMode="scrollable"/>

これにより、すべてのタブの背景を設定する代わりに、背景をtabLayoutの背後に設定します。

28
Rohit

これを試してください。tabMaxWidth="0dp"tabGravity="fill"、およびtabMode="fixed"を設定する回避策です。

 <Android.support.v4.view.ViewPager
     Android:id="@+id/container"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent"
     app:layout_behavior="@string/appbar_scrolling_view_behavior">
     <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"/>
</Android.support.v4.view.ViewPager>

10インチタブレットのスクリーンショット:

screenshot

21
Chandler

この問題を確実に解決するためにこれを使用してください

<Android.support.design.widget.TabLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed" />
3
Gurjeet Singh

この変更を試してください

 <Android.support.design.widget.TabLayout
        Android:id="@+id/sliding_tabs"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill" />
2
rKrishna

このソリューションは、Androidタブを作成し、タブの合計幅を計算します。タブが画面幅に収まるかどうかを確認し、収まる場合は、tabModeを「fixed」に設定します。画面幅に合わせてすべてのタブを拡大縮小します。

タブレイアウトxml、親は関係ありません:

<com.google.Android.material.tabs.TabLayout
        Android:id="@+id/tabs"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:tabMode="scrollable"/>

次に、アクティビティonCreateまたはフラグメントonCreateViewで:

var totalWidth = 0
var maxWidth = 0
for (i in 0 until tabLayout.tabCount) {
    val tabWidth = (tabLayout.getChildAt(0) as ViewGroup).getChildAt(i)!!.width
    totalWidth += tabWidth
    maxWidth = max(maxWidth, tabWidth)
}
val screenWidth = Resources.getSystem().displayMetrics.widthPixels

if (totalWidth <  screenWidth&& screenWidth/ tabLayout.tabCount >= maxWidth) {

    tabLayout.tabMode = TabLayout.MODE_FIXED
}

ViewpagerでTabLayoutを使用している場合、タブは開始時に膨らまないため、layoutChangeListenerを設定する必要があります。

アクティビティonCreateまたはフラグメントonCreateViewで:

tabLayout.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
    var totalWidth = 0
    var maxWidth = 0
    for (i in 0 until tabLayout.tabCount) {
        val tabWidth = (tabLayout.getChildAt(0) as ViewGroup).getChildAt(i)!!.width
        totalWidth += tabWidth
        maxWidth = max(maxWidth, tabWidth)
    }

     val screenWidth = Resources.getSystem().displayMetrics.widthPixels

    if (totalWidth < screenWidth && screenWidth / tabLayout.tabCount >= maxWidth) {

        tabLayout.tabMode = TabLayout.MODE_FIXED
    }
}

注:tabModeが「fixed」のときにすべてのタブのテキストサイズを同じにしたい場合は、styles.xmlからtextSizeを手動で設定する必要があります。

1
Sakox

私も苦労していましたが、上記のほとんどのオプションは機能しませんでした。そのため、DTX12の回答に基づいてバージョンを作成しました。

タブレットをチェックするかどうか、横向きと縦向きをチェックするブール値があります。次に、タブの量に基づいてレイアウトを設定します。

メソッドをpublicにして、rotation/configurationchangeで呼び出す必要がある場合があります。

CustomTabLayout Codeで、mintabswidthメソッドを置き換えました

private void initTabMinWidth()
{



    boolean isTablet = getContext().getResources().getBoolean(R.bool.device_is_tablet);
    boolean isLandscape = (wh[WIDTH_INDEX] > wh[HEIGHT_INDEX]) ? true : false;


    if (isTablet)
    {
        if (isLandscape)
        {
            if (this.getTabCount() > 8)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        } else
        {
            if (this.getTabCount() > 6)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        }
    } else
    {
        if (isLandscape)
        {
            if (this.getTabCount() > 6)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        } else
        {
            if (this.getTabCount() > 4)
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_SCROLLABLE);
            } else
            {
                this.setTabGravity(TabLayout.GRAVITY_FILL);
                this.setTabMode(TabLayout.MODE_FIXED);
            }
        }
    }


}
0
renevdkooi

Tablayoutでapp:tabMaxWidth = "0dp"を使用できます

0
Rahul Gupta

問題を解明するために2日間を費やした後、ようやく問題が解決しました。 @Tyler Vの答えを参照してください ここをチェック Tylerの答えから 'super.onMeasure()を呼び出す前に最小幅を設定することが重要でした。 'は非常に重要です

0
Sadashiv

この方法でそれを行い、app:tabMaxWidth="0dp"を追加し、app:tabGravity="fill"も使用します

<Android.support.design.widget.TabLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed" />
0
H.Fa8