태블릿 장치에서 탭이 전체 너비를 차지하지 않음 [android.support.design.widget.TabLayout 사용]


203

게시물에 업데이트29/05/2015 로 설정 탭 있습니다. 탭은 Nexus 4 휴대 전화에서 전체 너비를 차지하지만 nexus 7 태블릿에서는 전체 화면 너비를 가리지 않고 중앙에 배치합니다.

Nexus 7 스크린 샷 넥서스 7 Nexus 4 스크린 샷 넥서스 4


6 시간 동안 똑같은 문제로 어려움을 겪었지만 탭에만 문제가 있다는 것을 알지 못했습니다 ...
스택 오버 플로우에

질문에 태그를 더 추가해보십시오 ... (나 같은 사람들에게 더 도움이 될 것입니다.)이 질문은 Google 검색 목록의 세 번째 페이지에서 발견 되었기 때문에
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를 변경하면이 솔루션이 중단됩니다.
Tiago

3
스크롤 가능한 솔루션이 있습니까?
sunlover3

5
안녕하세요 .. 나는 이것을 추가하려고했습니다. 그러나 단일 탭은 탭 레이아웃의 전체 너비를 사용하지 않습니다.
Surinder

3
이 솔루션은 tabMode가 설정되지 않은 경우에도 작동합니다. 스크롤 가능한 tapMode는 채워진 중력 및 0dp 최대 너비의 기능을 지원하지 않는 것 같습니다.
Julio Mendoza

3
그래도 왜 발생합니까? 기본 동작입니까? 아니면 내가 잘 사용하지 않은 것? 탭을 중간에 설정하는 것이 지침의 일부입니까? 이것은 3+ 탭을 사용할 때 발생하지 않습니다. 2 개의 탭에만 해당됩니다.
안드로이드 개발자

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가 기본 스타일을 변경하지 않고 제어 할 수있는 것처럼 보입니다. tabMaxWidth는 진정한 범인처럼 보인다
kandroidj

3
이것은 셜록의 에피소드와 같습니다. 감사합니다!!
Lisa Wray

29

스크롤 가능 솔루션 : (TabLayout.MODE_SCROLLABLE), 3 개 이상의 탭 (동적 탭)이 필요할 때

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

    }

이것은 하나 이상의 탭에서만 작동했습니다. 탭이 하나만 있으면 탭이 탭 레이아웃을 채우지 않습니다. 이 문제를 해결하기 위해 app : tabMaxWidth = "1000dp"를 추가했으며 작동했습니다.
jzeferino

이것은 나를 위해 가장 잘 작동했습니다. 내 사용자 정의 탭 레이아웃 클래스에서 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

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

스크롤 가능 솔루션 (코 틀린)

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"XML로 TabLayout을 넣으 십시오. 그게 다야.

여기에 이미지 설명을 입력하십시오


1
3 개의 탭이 있으면 어떻게합니까? 화면에 맞지 않는 (서버 API에서 나오는 탭은 동적 임) 탭은 런타임에 알려져 있습니다.
Ram Prakash Bhat

그런 다음 프로그래밍 방식으로 다음과 같이 설정할 수도 있습니다. tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);또한 이것은 tabLayout에 설정하는 속성 일뿐입니다. 정적 또는 동적으로 추가하는 탭 수는 중요하지 않습니다.
Ali Akram

텍스트 크기에 따라 탭 너비가 설정됩니다. 이미지로 편집 된 답변을 확인하십시오.
Ali Akram

이 경우 탭 모드에서 씨야 SCROLLABLE 다음 말에 유 빈 공간 이잖아 이상한 모양 볼 것이다
램 프라 카시 바트

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"

모든 공간을 채우기 위해


스택 오버플로에 오신 것을 환영합니다. 하시기 바랍니다 여행을 . 토론 포럼이 아닌 질문 및 답변 사이트입니다. 이 섹션은 완전한 답변을위한 것입니다. 질문과 답변으로 50 점의 평판을 얻은 후에는 다른 사용자의 질문과 답변에 의견제시 할 수 있습니다 .
Chris
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.