Thiết kế hỗ trợ Android TabLayout: Trung tâm trọng lực và Chế độ có thể cuộn


98

Tôi đang cố gắng sử dụng TabLayout thiết kế mới trong dự án của mình. Tôi muốn bố cục thích ứng với mọi kích thước và hướng màn hình, nhưng nó có thể được nhìn thấy chính xác theo một hướng.

Tôi đang xử lý Gravity và Mode đặt tabLayout của mình là:

    tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

Vì vậy, tôi hy vọng rằng nếu không có chỗ trống, tabLayout có thể cuộn được, nhưng nếu có chỗ, nó sẽ được căn giữa.

Từ các hướng dẫn:

public static final int GRAVITY_CENTER Gravity được sử dụng để bố trí các tab ở giữa TabLayout.

public static final int GRAVITY_FILL Gravity được sử dụng để lấp đầy TabLayout nhiều nhất có thể. Tùy chọn này chỉ có hiệu lực khi được sử dụng với MODE_FIXED.

public static final int MODE_FIXED Các tab cố định hiển thị đồng thời tất cả các tab và được sử dụng tốt nhất với nội dung được hưởng lợi từ việc xoay vòng nhanh giữa các tab. Số lượng tab tối đa bị giới hạn bởi chiều rộng của chế độ xem. Các tab cố định có chiều rộng bằng nhau, dựa trên nhãn tab rộng nhất.

public static final int MODE_SCROLLABLE Các tab có thể cuộn được hiển thị một tập hợp con các tab tại bất kỳ thời điểm nào và có thể chứa các nhãn tab dài hơn và số lượng tab lớn hơn. Chúng được sử dụng tốt nhất để duyệt các ngữ cảnh trong giao diện cảm ứng khi người dùng không cần so sánh trực tiếp các nhãn tab.

Vì vậy, GRAVITY_FILL chỉ tương thích với MODE_FIXED nhưng tại không chỉ định bất kỳ điều gì cho GRAVITY_CENTER, tôi hy vọng nó sẽ tương thích với MODE_SCROLLABLE, nhưng đây là những gì tôi nhận được khi sử dụng GRAVITY_CENTER và MODE_SCROLLABLE

nhập mô tả hình ảnh ở đây

Vì vậy, nó đang sử dụng SCROLLABLE ở cả hai hướng, nhưng nó không sử dụng GRAVITY_CENTER.

Đây là những gì tôi mong đợi cho cảnh quan; nhưng để có điều này, tôi cần đặt MODE_FIXED, vì vậy những gì tôi nhận được ở chế độ dọc là:

nhập mô tả hình ảnh ở đây

Tại sao GRAVITY_CENTER không hoạt động cho SCROLLABLE nếu tabLayout vừa với màn hình? Có cách nào để đặt trọng lực và chế độ động (và để xem những gì tôi đang mong đợi)?

Cảm ơn rât nhiều!

ĐÃ CHỈNH SỬA: Đây là Bố cục của TabLayout của tôi:

<android.support.design.widget.TabLayout
    android:id="@+id/sliding_tabs"
    android:layout_width="match_parent"
    android:background="@color/orange_pager"
    android:layout_height="wrap_content" />

@ Fighter42 bạn đã tìm thấy giải pháp nào cho việc này chưa? Tôi đang đối mặt với vấn đề tương tự.
Spynet

Cách duy nhất tôi tìm thấy là lấy kích thước của các tab của bạn (theo cách thủ công) và sau đó định cấu hình các thông số bố cục một cách linh động tùy thuộc vào nó có phù hợp hay không.
Javier Delgado

@ Fighter42, bạn có thể đăng một số mã mẫu cho giải pháp mà bạn đang sử dụng không?
Sammys

1
Tôi biết rằng câu trả lời của tôi không tốt cho logic nhưng nó có ích cho tôi. Đặt một số khoảng trắng trước và sau văn bản. Sau đó, nó sẽ có thể cuộn được. ở cả hai chế độ.
AmmY

Câu trả lời:


127

Tab trọng lực chỉ có tác dụng MODE_FIXED.

Một giải pháp khả thi là để thiết lập của bạn layout_widthđể wrap_contentlayout_gravityđể center_horizontal:

<android.support.design.widget.TabLayout
    android:id="@+id/sliding_tabs"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    app:tabMode="scrollable" />

Nếu các tab nhỏ hơn chiều rộng màn hình, TabLayoutbản thân các tab cũng sẽ nhỏ hơn và nó sẽ được căn giữa vì trọng lực. Nếu các tab lớn hơn chiều rộng màn hình, tab TabLayoutsẽ khớp với chiều rộng màn hình và thao tác cuộn sẽ kích hoạt.


1
Tôi đang sử dụng thiết kế Material design cho ứng dụng của mình. Tôi đã làm theo mẫu từ androidhive.info/2015/09/… Tab có thể cuộn được không hoạt động trong các thiết bị Kitkat và Jelly bean. Trong kẹo mút, tôi có thể cuộn Tab nhưng trong các thiết bị khác ngoài kẹo mút, Tab có thể cuộn không hoạt động nhưng vuốt hoạt động tốt. Tôi có thể biết những gì sẽ là vấn đề.
user2681579

Điều này không hiệu quả với tôi trên API 15 / support.design:25.1.0. Các tab được căn trái khi hẹp hơn chiều rộng cửa sổ. Đặt app:tabMaxWidth="0dp"android:layout_centerHorizontal="true"làm việc với các tab ở giữa.
Baker

1
Nó đã làm việc cho tôi. Các tab luôn được căn giữa, nhưng khi chúng không thực sự cuộn được, chúng không lấp đầy toàn bộ chiều rộng.
José Augustinho

14

đây là cách tôi đã làm nó

TabLayout.xml

<android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:background="@android:color/transparent"
            app:tabGravity="fill"
            app:tabMode="scrollable"
            app:tabTextAppearance="@style/TextAppearance.Design.Tab"
            app:tabSelectedTextColor="@color/myPrimaryColor"
            app:tabIndicatorColor="@color/myPrimaryColor"
            android:overScrollMode="never"
            />

Oncreate

@Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
        mTabLayout = (TabLayout)findViewById(R.id.tab_layout);
        mTabLayout.setOnTabSelectedListener(this);
        setSupportActionBar(mToolbar);

        mTabLayout.addTab(mTabLayout.newTab().setText("Dashboard"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Signature"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Booking/Sampling"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Calendar"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Customer Detail"));

        mTabLayout.post(mTabLayout_config);
    }

    Runnable mTabLayout_config = new Runnable()
    {
        @Override
        public void run()
        {

           if(mTabLayout.getWidth() < MainActivity.this.getResources().getDisplayMetrics().widthPixels)
            {
                mTabLayout.setTabMode(TabLayout.MODE_FIXED);
                ViewGroup.LayoutParams mParams = mTabLayout.getLayoutParams();
                mParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
                mTabLayout.setLayoutParams(mParams);

            }
            else
            {
                mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }
        }
    };

Tôi đã thực hiện các thay đổi nhỏ về giải pháp của @Mario Velasco ở phần chạy được


Giải pháp này có cùng những vấn đề mà tôi đã đề cập trên giải pháp của Tiago.
Sotti

Giải pháp này hoạt động trên tab không có biểu tượng, điều gì sẽ xảy ra nếu tôi có biểu tượng với văn bản ?? : /
Emre Tekin

@EmreTekin có nó làm việc với một biểu tượng, các tab của tôi có biểu tượng với văn bản
Flux

tabLayout.getWidth()luôn luôn trở về số không đối với tôi
ishandutta2007

9

giúp mọi thứ đơn giản chỉ cần thêm ứng dụng: tabMode = "scrollable" và android: layout_gravity = "bottom"

chỉ như thế này

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:tabMode="scrollable"
app:tabIndicatorColor="@color/colorAccent" />

nhập mô tả hình ảnh ở đây


7
Đây không phải là những gì người sáng tạo đang yêu cầu. Vấn đề với cách tiếp cận này là trong các tình huống mà bạn có 2 tab hoặc 3 3 tab trên điện thoại mà văn bản nhỏ, bạn sẽ có bố cục giống như Cửa hàng Google Play với các tab ở bên trái. Người sáng tạo muốn các tab tiếp cận từ mép này sang mép khác khi có thể và cuộn theo cách khác.
Sotti

Cùng một vấn đề. Bạn có thể sửa chữa nó?
Hoàng Đức Tuấn

8

Vì tôi không tìm thấy lý do tại sao hành vi này xảy ra, tôi đã sử dụng mã sau:

float myTabLayoutSize = 360;
if (DeviceInfo.getWidthDP(this) >= myTabLayoutSize ){
    tabLayout.setTabMode(TabLayout.MODE_FIXED);
} else {
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
}

Về cơ bản, tôi phải tính toán thủ công chiều rộng của tabLayout của mình và sau đó tôi đặt Chế độ tab tùy thuộc vào việc tabLayout có vừa với thiết bị hay không.

Lý do tại sao tôi nhận được kích thước của bố cục theo cách thủ công là vì không phải tất cả các tab đều có cùng chiều rộng trong chế độ Có thể cuộn và điều này có thể dẫn đến việc một số tên sử dụng 2 dòng như nó đã xảy ra với tôi trong ví dụ.


Với giải pháp này, văn bản có thể được thu nhỏ và sử dụng 2 dòng. Xem các câu trả lời và giải pháp khác trong chủ đề này về nó. Bạn đang giảm nguy cơ điều này xuất hiện nhưng vẫn sẽ xuất hiện thường xuyên khi TabLayout nhỏ hơn một chút so với screenWidth.
Sotti

7

Nhìn vào android-tablayouthelper

Tự động chuyển đổi TabLayout.MODE_FIXED và TabLayout.MODE_SCROLLABLE tùy thuộc vào tổng chiều rộng tab.


Nhưng khi Tiêu đề tab là động. Văn bản ở dòng tiếp theo. Và Nếu sử dụng Bố cục tùy chỉnh cho tab. Văn bản ellipsize ở cuối như
AndroidGeek

4

Đây là giải pháp tôi đã sử dụng để tự động thay đổi giữa SCROLLABLEFIXED+ FILL. Đây là mã hoàn chỉnh cho giải pháp @ Fighter42:

(Đoạn mã dưới đây cho biết nơi đặt sửa đổi nếu bạn đã sử dụng mẫu hoạt động theo tab của Google)

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    // Set up the tabs
    final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

    // Mario Velasco's code
    tabLayout.post(new Runnable()
    {
        @Override
        public void run()
        {
            int tabLayoutWidth = tabLayout.getWidth();

            DisplayMetrics metrics = new DisplayMetrics();
            ActivityMain.this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int deviceWidth = metrics.widthPixels;

            if (tabLayoutWidth < deviceWidth)
            {
                tabLayout.setTabMode(TabLayout.MODE_FIXED);
                tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
            } else
            {
                tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }
        }
    });
}

Bố trí:

    <android.support.design.widget.TabLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

Nếu bạn không cần điền chiều rộng, tốt hơn nên sử dụng giải pháp @karaokyo.


cái này hoạt động tốt; chuyển đổi giữa phong cảnh và dọc thực hiện chính xác những gì bạn có thể mong đợi. Google nên triển khai điều này trong mẫu mặc định cho hoạt động theo tab.
Ai đó ở đâu đó

Câu trả lời này có cùng những vấn đề mà tôi đã đề cập trong giải pháp của Tiago.
Sotti

4

Tôi đã tạo một lớp AdaptiveTabLayout để đạt được điều này. Đây là cách duy nhất tôi tìm thấy để thực sự giải quyết vấn đề, trả lời câu hỏi và tránh / giải quyết các vấn đề mà các câu trả lời khác ở đây không làm được.

Ghi chú:

  • Xử lý bố cục điện thoại / máy tính bảng.
  • Xử lý các trường hợp có đủ chỗ MODE_SCROLLABLEnhưng không đủ chỗ MODE_FIXED. Nếu bạn không xử lý trường hợp này, nó sẽ xảy ra trên một số thiết bị, bạn sẽ thấy các kích thước văn bản khác nhau hoặc hiển thị hai dòng văn bản trong một số tab, trông rất tệ.
  • Nó có các thước đo thực tế và không đưa ra bất kỳ giả định nào (như màn hình rộng 360dp hoặc bất cứ thứ gì ...). Điều này hoạt động với kích thước màn hình thực và kích thước tab thực. Điều này có nghĩa là hoạt động tốt với các bản dịch vì không giả sử bất kỳ kích thước tab nào, các tab sẽ được đo lường.
  • Thỏa thuận với các đường chuyền khác nhau trong giai đoạn OnLayout để tránh làm việc thêm.
  • Chiều rộng bố cục cần phải nằm wrap_contenttrên xml. Không đặt bất kỳ chế độ hoặc trọng lực nào trên xml.

AdaptiveTabLayout.java

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class AdaptiveTabLayout extends TabLayout
{
    private boolean mGravityAndModeSeUpNeeded = true;

    public AdaptiveTabLayout(@NonNull final Context context)
    {
        this(context, null);
    }

    public AdaptiveTabLayout(@NonNull final Context context, @Nullable final AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public AdaptiveTabLayout
    (
            @NonNull final Context context,
            @Nullable final AttributeSet attrs,
            final int defStyleAttr
    )
    {
        super(context, attrs, defStyleAttr);
        setTabMode(MODE_SCROLLABLE);
    }

    @Override
    protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b)
    {
        super.onLayout(changed, l, t, r, b);

        if (mGravityAndModeSeUpNeeded)
        {
            setModeAndGravity();
        }
    }

    private void setModeAndGravity()
    {
        final int tabCount = getTabCount();
        final int screenWidth = UtilsDevice.getScreenWidth();
        final int minWidthNeedForMixedMode = getMinSpaceNeededForFixedMode(tabCount);

        if (minWidthNeedForMixedMode == 0)
        {
            return;
        }
        else if (minWidthNeedForMixedMode < screenWidth)
        {
            setTabMode(MODE_FIXED);
            setTabGravity(UtilsDevice.isBigTablet() ? GRAVITY_CENTER : GRAVITY_FILL) ;
        }
        else
        {
            setTabMode(TabLayout.MODE_SCROLLABLE);
        }

        setLayoutParams(new LinearLayout.LayoutParams
                (LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

        mGravityAndModeSeUpNeeded = false;
    }

    private int getMinSpaceNeededForFixedMode(final int tabCount)
    {
        final LinearLayout linearLayout = (LinearLayout) getChildAt(0);
        int widestTab = 0;
        int currentWidth;

        for (int i = 0; i < tabCount; i++)
        {
            currentWidth = linearLayout.getChildAt(i).getWidth();

            if (currentWidth == 0) return 0;

            if (currentWidth > widestTab)
            {
                widestTab = currentWidth;
            }
        }

        return widestTab * tabCount;
    }

}

Và đây là lớp DeviceUtils:

import android.content.res.Resources;

public class UtilsDevice extends Utils
{
    private static final int sWIDTH_FOR_BIG_TABLET_IN_DP = 720;

    private UtilsDevice() {}

    public static int pixelToDp(final int pixels)
    {
        return (int) (pixels / Resources.getSystem().getDisplayMetrics().density);
    }

    public static int getScreenWidth()
    {
        return Resources
                .getSystem()
                .getDisplayMetrics()
                .widthPixels;
    }

    public static boolean isBigTablet()
    {
        return pixelToDp(getScreenWidth()) >= sWIDTH_FOR_BIG_TABLET_IN_DP;
    }

}

Sử dụng ví dụ:

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.com.stackoverflow.example.AdaptiveTabLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="?colorPrimary"
        app:tabIndicatorColor="@color/white"
        app:tabSelectedTextColor="@color/text_white_primary"
        app:tabTextColor="@color/text_white_secondary"
        tools:layout_width="match_parent"/>

</FrameLayout>

Ý chính

Sự cố / Yêu cầu trợ giúp:

  • Bạn sẽ thấy điều này:

Logcat:

W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$SlidingTabStrip{3e1ebcd6 V.ED.... ......ID 0,0-466,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{3423cb57 VFE...C. ..S...ID 0,0-144,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{377c4644 VFE...C. ......ID 144,0-322,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{19ead32d VFE...C. ......ID 322,0-466,96} during layout: running second layout pass

Tôi không chắc làm thế nào để giải quyết nó. Bất kỳ đề xuất?

  • Để thực hiện các phép đo con của TabLayout, tôi đang thực hiện một số đúc và giả định (Giống như con là một LinearLayout chứa các khung nhìn khác ....) Điều này có thể gây ra sự cố trong các bản cập nhật Thư viện hỗ trợ thiết kế. Một cách tiếp cận / đề xuất tốt hơn?

4
 <android.support.design.widget.TabLayout
                    android:id="@+id/tabList"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    app:tabMode="scrollable"/>

1

Đây là mã duy nhất phù hợp với tôi:

public static void adjustTabLayoutBounds(final TabLayout tabLayout,
                                         final DisplayMetrics displayMetrics){

    final ViewTreeObserver vto = tabLayout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {

            tabLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            int totalTabPaddingPlusWidth = 0;
            for(int i=0; i < tabLayout.getTabCount(); i++){

                final LinearLayout tabView = ((LinearLayout)((LinearLayout) tabLayout.getChildAt(0)).getChildAt(i));
                totalTabPaddingPlusWidth += (tabView.getMeasuredWidth() + tabView.getPaddingLeft() + tabView.getPaddingRight());
            }

            if (totalTabPaddingPlusWidth <= displayMetrics.widthPixels){

                tabLayout.setTabMode(TabLayout.MODE_FIXED);
                tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

            }else{
                tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }

            tabLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        }
    });
}

DisplayMetrics có thể được truy xuất bằng cách sử dụng:

public DisplayMetrics getDisplayMetrics() {

    final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    final Display display = wm.getDefaultDisplay();
    final DisplayMetrics displayMetrics = new DisplayMetrics();

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        display.getMetrics(displayMetrics);

    }else{
        display.getRealMetrics(displayMetrics);
    }

    return displayMetrics;
}

Và TabLayout XML của bạn sẽ trông như thế này (đừng quên đặt tabMaxWidth thành 0):

<android.support.design.widget.TabLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tab_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:tabMaxWidth="0dp"/>

1
Điều này gần đạt được nhưng có một số vấn đề. Vấn đề rõ ràng nhất là trong một số thiết bị (và hầu hết những thiết bị chậm), bạn sẽ thực sự thấy bố cục được sửa đổi và thay đổi như thế nào.
Sotti

1
Có một vấn đề khác, cách tiếp cận này đo tổng chiều rộng của TabLayout để quyết định xem có cuộn được hay không. Điều đó không chính xác lắm. Có những tình huống mà TabLayout không đạt được cả hai cạnh trong khi ở chế độ có thể cuộn, nhưng không có đủ chỗ cho chế độ cố định mà không thu nhỏ văn bản lạm dụng số dòng trên tab (thường là 2). Đây là hệ quả trực tiếp của việc các tab ở chế độ cố định có chiều rộng cố định (screenWidth / numberOfTabs) trong khi ở chế độ có thể cuộn, chúng đang bao bọc văn bản + đệm.
Sotti

1

Tất cả những gì bạn cần là thêm phần sau vào TabLayout của mình

custom:tabGravity="fill"

Vì vậy, sau đó bạn sẽ có:

xmlns:custom="http://schemas.android.com/apk/res-auto"
<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        custom:tabGravity="fill"
        />

Đây không phải là những gì người sáng tạo đang yêu cầu. Vấn đề ở đây là các tab sẽ không bao giờ có thể cuộn được và bạn sẽ loại bỏ không gian trên màn hình. Các tab sẽ bắt đầu thu nhỏ văn bản của nó và cuối cùng chúng sẽ xếp thành hai hàng.
Sotti

1

Tôi đã giải quyết vấn đề này bằng cách sử dụng sau

if(tabLayout_chemistCategory.getTabCount()<4)
    {
        tabLayout_chemistCategory.setTabGravity(TabLayout.GRAVITY_FILL);
    }else
    {
        tabLayout_chemistCategory.setTabMode(TabLayout.MODE_SCROLLABLE);

    }

1

Ví dụ rất đơn giản và nó luôn hoạt động.

/**
 * Setup stretch and scrollable TabLayout.
 * The TabLayout initial parameters in layout must be:
 * android:layout_width="wrap_content"
 * app:tabMaxWidth="0dp"
 * app:tabGravity="fill"
 * app:tabMode="fixed"
 *
 * @param context   your Context
 * @param tabLayout your TabLayout
 */
public static void setupStretchTabLayout(Context context, TabLayout tabLayout) {
    tabLayout.post(() -> {

        ViewGroup.LayoutParams params = tabLayout.getLayoutParams();
        if (params.width == ViewGroup.LayoutParams.MATCH_PARENT) { // is already set up for stretch
            return;
        }

        int deviceWidth = context.getResources()
                                 .getDisplayMetrics().widthPixels;

        if (tabLayout.getWidth() < deviceWidth) {
            tabLayout.setTabMode(TabLayout.MODE_FIXED);
            params.width = ViewGroup.LayoutParams.MATCH_PARENT;
        } else {
            tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
        }
        tabLayout.setLayoutParams(params);

    });

}

Cảm ơn vì ý tưởng. Với một chút thay đổi cho trường hợp của tôi, hoạt động giống như sự quyến rũ
Eren Tüfekçi

1

Giải pháp cuối cùng của tôi

class DynamicModeTabLayout : TabLayout {

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun setupWithViewPager(viewPager: ViewPager?) {
        super.setupWithViewPager(viewPager)

        val view = getChildAt(0) ?: return
        view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
        val size = view.measuredWidth

        if (size > measuredWidth) {
            tabMode = MODE_SCROLLABLE
            tabGravity = GRAVITY_CENTER
        } else {
            tabMode = MODE_FIXED
            tabGravity = GRAVITY_FILL
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.