当 tabMode 设置为“可滚动”时,TabLayout 不填充宽度
Posted
技术标签:
【中文标题】当 tabMode 设置为“可滚动”时,TabLayout 不填充宽度【英文标题】:TabLayout not filling width when tabMode set to 'scrollable' 【发布时间】:2015-12-12 14:46:59 【问题描述】:我已将TabLayout
(来自支持库 v22.2.1)添加到我的片段中:
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
style="@style/MyColorAccentTabLayout"
android:layout_
android:layout_
app:tabMode="scrollable"/>
问题是当片段的方向是横向时(在片段初始创建之前或之后),TabLayout
与Fragment
的宽度不匹配(是的,父级的宽度设置为@ 987654331@也一样)。
当屏幕宽度较小时(即不能同时显示所有选项卡):
当屏幕宽度足够大以显示所有选项卡时(请参阅右侧的空白区域):
如果我将tabMode
更改为固定,则宽度已填充但选项卡太小。有没有合适的解决方案?
【问题讨论】:
看看这个线程:***.com/questions/31698756/…,也看看这个:code.google.com/p/android/issues/detail?id=175516(仍然没有修复 imo) 【参考方案1】:我想这是实现你想要的最简单的方法。
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();
【讨论】:
太棒了!抱歉耽搁了。我忙于其他事情,所以我无法测试这个。我认为谷歌应该解决这个问题。我很惊讶他们如何允许半生不熟的东西出来。mTabMinWidth
在设计支持库版本 23.1.1 上不存在
在新的支持库中,它被称为“mScrollableTabMinWidth”
在 28.0.0 中它的'scrollableTabMinWidth'
我必须在 layout.xml 中将 tabMode 定义为 'fixed' 并且还需要添加 'setTabMode(MODE_SCROLLABLE);'在 onMeasure 结束时。 (因为 TabLayout 在模式之间切换时会重新计算其选项卡。仅更改可滚动选项卡的宽度并不会使其重新计算选项卡。【参考方案2】:
试试这个改动
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_
android:layout_
app:tabMode="fixed"
app:tabGravity="fill" />
【讨论】:
请再次阅读我的问题。我已经提到我已经尝试过了。 固定屏幕宽度时标签会变小 我刚刚对这个答案投了赞成票,但在我的情况下,我从两个选项卡开始,固定模式可以根据需要将它们拉伸并居中。然后我在应用会话期间动态添加更多选项卡,然后我以编程方式将模式更改为可滚动。 添加 app:tabGravity="fill" 对我有用,因为我想拥有最多 3 个标签的固定模式【参考方案3】:我不关心标签填充宽度,但我关心背景颜色没有扩展到整个宽度。所以我想到了这个解决方案,我在它后面放了一个与标签相同的背景颜色的 FrameLayout。
<FrameLayout
android:layout_
android:layout_
android:background="@color/MyColor">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
style="@style/MyCustomTabLayout"
android:layout_
android:layout_
app:tabMode="scrollable"/>
</FrameLayout>
【讨论】:
【参考方案4】:而不是创建自定义 TabLayout 和修改或创建更多的布局,这些布局仅作为背景的 TabLayout 的包装器。试试这个,
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
style="@style/MyColorAccentTabLayout"
android:layout_
android:layout_
<!-- Instead of setting app:tabBackground -->
android:background="@color/colorAccent"
app:tabGravity="fill"
app:tabMode="scrollable"/>
这会将背景设置在 tabLayout 后面,而不是在每个选项卡后面设置背景。
【讨论】:
【参考方案5】:如果任何选项卡标题大于 (measuredWidth/tabCount),@dtx12 答案将不起作用。
我的 TabLayout
子类适用于这种情况(在 Kotlin 中)。我希望这会对某人有所帮助。
class FullWidthTabLayout : 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 onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int)
super.onLayout(changed, l, t, r, b)
if (changed)
val widths = mutableListOf<Int>()
for (i in 0..this.tabCount - 1)
widths.add(this.getTabAt(i)!!.customView!!.width)
if (widths.sum() < this.measuredWidth)
var equalPart: Long = this.measuredWidth.toLong() / this.tabCount.toLong()
var biggerWidths = widths.filter it > equalPart
var smallerWidths = widths.filter it <= equalPart
var rest: Long = this.measuredWidth.toLong() - biggerWidths.sum()
while (biggerWidths.size != 0)
equalPart = rest / smallerWidths.size
biggerWidths = smallerWidths.filter it >= equalPart
smallerWidths = smallerWidths.filter it < equalPart
rest -= biggerWidths.sum()
val minWidth = (rest / smallerWidths.size) + 10 //dont know why there is small gap on the end, thats why +10
for (i in 0..this.tabCount - 1)
this.getTabAt(i)!!.customView!!.minimumWidth = minWidth.toInt()
【讨论】:
我遇到了类似的问题,Kotlin 也帮不上忙——开发人员使用 Java。当只有少数开发人员真正在商业产品中使用这些语言时,这就像在 Scala 或 Groovy 中提供解决方案一样。【参考方案6】:请用这个绝对可以解决这个问题
<android.support.design.widget.TabLayout
android:layout_
android:layout_
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed" />
【讨论】:
这绝对是最好的解决方案,如果没有“tabMaxWidth="0dp"”,该解决方案不适用于三星 Tab4 等某些设备。所以这对我来说是最好的解决方案。谢谢。 也适合我。【参考方案7】:请检查一下我认为它有效
公共类 MainActivity 扩展 AppCompatActivity
private TextView mTxv_Home, mTxv_News, mTxv_Announcement;
private View mView_Home, mView_News, mView_Announcements;
private HorizontalScrollView hsv;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxv_Home = (TextView) findViewById(R.id.txv_home);
mTxv_News = (TextView) findViewById(R.id.txv_news);
mTxv_Announcement = (TextView) findViewById(R.id.txv_announcements);
mView_Home = (View) findViewById(R.id.view_home);
mView_News = (View) findViewById(R.id.view_news);
mView_Announcements = (View) findViewById(R.id.view_announcements);
hsv = (HorizontalScrollView) findViewById(R.id.hsv);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int wt = displaymetrics.widthPixels/3;
mTxv_Home.setWidth(wt);
mTxv_News.setWidth(wt);
// mTxv_Announcement.setWidth(wt);
mTxv_Home.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
mTxv_Home.setTextColor(Color.parseColor("#3F51B5"));
mTxv_News.setTextColor(Color.parseColor("#808080"));
mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
mView_Home.setBackgroundColor(Color.parseColor("#3F51B5"));
mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
hsv.post(new Runnable()
public void run()
hsv.fullScroll(HorizontalScrollView.FOCUS_LEFT);
);
viewPager.setCurrentItem(0);
);
mTxv_News.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
mTxv_Home.setTextColor(Color.parseColor("#808080"));
mTxv_News.setTextColor(Color.parseColor("#3F51B5"));
mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_News.setBackgroundColor(Color.parseColor("#3F51B5"));
mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
hsv.post(new Runnable()
public void run()
int centerX = hsv.getChildAt(0).getWidth()/2;
hsv.scrollTo(centerX, 0);
);
viewPager.setCurrentItem(1);
);
mTxv_Announcement.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
mTxv_Home.setTextColor(Color.parseColor("#808080"));
mTxv_News.setTextColor(Color.parseColor("#808080"));
mTxv_Announcement.setTextColor(Color.parseColor("#3F51B5"));
mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_Announcements.setBackgroundColor(Color.parseColor("#3F51B5"));
hsv.post(new Runnable()
public void run()
hsv.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
);
viewPager.setCurrentItem(2);
);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
@Override
public void onPageSelected(int position)
if (position == 0)
mTxv_Home.setTextColor(Color.parseColor("#3F51B5"));
mTxv_News.setTextColor(Color.parseColor("#808080"));
mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
mView_Home.setBackgroundColor(Color.parseColor("#3F51B5"));
mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
hsv.post(new Runnable()
public void run()
hsv.fullScroll(HorizontalScrollView.FOCUS_LEFT);
);
else if (position == 1)
mTxv_Home.setTextColor(Color.parseColor("#808080"));
mTxv_News.setTextColor(Color.parseColor("#3F51B5"));
mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_News.setBackgroundColor(Color.parseColor("#3F51B5"));
mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
hsv.post(new Runnable()
public void run()
int centerX = hsv.getChildAt(0).getWidth()/2;
hsv.scrollTo(centerX, 0);
);
else if (position == 2)
mTxv_Home.setTextColor(Color.parseColor("#808080"));
mTxv_News.setTextColor(Color.parseColor("#808080"));
mTxv_Announcement.setTextColor(Color.parseColor("#3F51B5"));
mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
mView_Announcements.setBackgroundColor(Color.parseColor("#3F51B5"));
hsv.post(new Runnable()
public void run()
hsv.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
);
@Override
public void onPageScrollStateChanged(int state)
);
private void setupViewPager(ViewPager viewPager)
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new HomeFragment(), "Home");
adapter.addFragment(new NewsFragment(), "News");
adapter.addFragment(new AnnouncementsFragment(), "Announcements");
viewPager.setAdapter(adapter);
class ViewPagerAdapter extends FragmentPagerAdapter
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager)
super(manager);
@Override
public Fragment getItem(int position)
return mFragmentList.get(position);
@Override
public int getCount()
return mFragmentList.size();
public void addFragment(Fragment fragment, String title)
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
@Override
public CharSequence getPageTitle(int position)
return mFragmentTitleList.get(position);
<HorizontalScrollView
android:id="@+id/hsv"
android:layout_
android:layout_
android:layout_weight="0"
android:fillViewport="true"
android:measureAllChildren="false"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/innerLay"
android:layout_
android:layout_
android:orientation="horizontal" >
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:id="@+id/txv_home"
android:layout_
android:layout_
android:layout_weight="1"
android:text="Home"
android:singleLine="true"
android:paddingLeft="35dp"
android:paddingRight="35dp"
android:gravity="center"
android:textSize="15sp"/>
<View
android:id="@+id/view_home"
android:layout_
android:layout_
android:background="@color/colorPrimary"
/>
</LinearLayout>
<View
android:layout_
android:layout_
android:visibility="gone"
android:background="#e8e8e8"/>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:id="@+id/txv_news"
android:layout_
android:layout_
android:layout_weight="1"
android:text="News"
android:singleLine="true"
android:paddingLeft="35dp"
android:paddingRight="35dp"
android:gravity="center"
android:textSize="15sp"/>
<View
android:id="@+id/view_news"
android:layout_
android:layout_
android:background="#e8e8e8"/>
</LinearLayout>
<View
android:layout_
android:layout_
android:visibility="gone"
android:background="#e8e8e8"/>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:id="@+id/txv_announcements"
android:layout_
android:layout_
android:layout_weight="1"
android:singleLine="true"
android:text="Announcements"
android:paddingLeft="35dp"
android:paddingRight="35dp"
android:gravity="center"
android:textSize="15sp"/>
<View
android:id="@+id/view_announcements"
android:layout_
android:layout_
android:background="#e8e8e8"/>
</LinearLayout>
</LinearLayout>
</HorizontalScrollView>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_
android:layout_
android:layout_below="@+id/hsv" />
【讨论】:
【参考方案8】:androidx 版本:
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_
android:layout_
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_
android:layout_
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed"
/>
</androidx.viewpager.widget.ViewPager>
***** 下面是旧答案 *****
试试这个,这是一种设置tabMaxWidth="0dp"
、tabGravity="fill"
和tabMode="fixed"
的解决方法。
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_
android:layout_
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_
android:layout_
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed"/>
</android.support.v4.view.ViewPager>
10 英寸平板电脑上的屏幕截图:
【讨论】:
你让我开心...谢谢 此解决方案不适合动态选项卡数,比如超过 5 个,因为它的 tabMode 是固定的 这不是问题的解决方案,因为当 tabMode 设置为“可滚动”时,作者要求填充宽度。在您的示例中,tabMode 设置为“固定” 请重新阅读问题,以及作者上传的截图。 你拯救了我的一天app:tabMaxWidth=“0dp”
谢谢兄弟【参考方案9】:
当你想显示标签“填充”时,你应该设置 app:tabMode="fixed"。
**<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_
android:layout_
android:layout_below="@+id/toolbar"
android:background="#353535"
app:tabMode="fixed"
android:minHeight="?attr/actionBarSize"
app:tabIndicatorColor="@color/red"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />**
【讨论】:
【参考方案10】:您可以在标签布局中使用 app:tabMaxWidth="0dp"
【讨论】:
【参考方案11】:我也在苦苦挣扎,上面的大多数选项都不适合我,所以我根据 DTX12 的答案创建了一个版本。
我有一个布尔值来检查平板电脑与否,并检查横向和纵向。然后根据标签的数量设置布局。
您可能需要公开该方法并在轮换/配置更改时调用它。
在 CustomTabLayout 代码中我替换了 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);
【讨论】:
【参考方案12】:花了 2 天时间解决了这个问题,现在终于对我有用了。请参阅@Tyler V 的回答check here 来自 Tyler 的回答 '在调用 super.onMeasure() 之前设置最小宽度是关键。' 非常重要
【讨论】:
【参考方案13】:此解决方案的工作原理是让 android 创建选项卡,然后计算它们的总宽度。然后检查选项卡是否适合屏幕宽度,如果适合则将 tabMode 设置为“固定”,这会缩放所有选项卡以适合屏幕宽度。
标签布局xml,父无关系:
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_
android:layout_
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
如果您将 TabLayout 与 Viewpager 一起使用,那么您必须设置一个 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 为“固定”时具有相同的文本大小,那么您必须从 styles.xml 手动设置 textSize。
【讨论】:
【参考方案14】:<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_
android:layout_
android:layout_gravity="center"
app:tabMode="scrollable"/>
【讨论】:
您必须将 layout_gravity 添加为 center 和 tabmode 可滚动 android:layout_gravity="center" 将标签标题垂直居中【参考方案15】:这里有一个更简单的方法来确保标签的宽度等于标签的字符串长度
<androidx.viewpager.widget.ViewPager
android:id="@+id/vpTabs"
android:layout_
android:layout_>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_
android:layout_
app:tabMaxWidth="0dp"
app:tabMode="scrollable"/>
</androidx.viewpager.widget.ViewPager>
使用以下代码:-
app:tabMaxWidth="0dp"
app:tabMode="scrollable"
【讨论】:
【参考方案16】:这是我将 tabMode 设置为的解决方案: app:tabMode="scrollable"
class MyTabLayout(
context: Context,
attrs: AttributeSet?
) : TabLayout(context, attrs)
override fun onMeasure(
widthMeasureSpec: Int,
heightMeasureSpec: Int
)
val equalTabWidth= (MeasureSpec.getSize(widthMeasureSpec) / tabCount.toFloat()).toInt()
for (index in 0..tabCount)
val tab = getTabAt(index)
val tabMeasuredWidth = tab?.view?.measuredWidth ?: equalTabWidth
if (tabMeasuredWidth < equalTabWidth)
tab?.view?.minimumWidth = equalTabWidth
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
【讨论】:
【参考方案17】:我已经尝试了几乎所有的答案,最后发现这个很有魅力。
public void dynamicSetTabLayoutMode(TabLayout tabLayout)
int tabWidth = calculateTabWidth(tabLayout);
int screenWidth = getApplicationContext().getResources().getDisplayMetrics().widthPixels;
if (tabWidth <= screenWidth)
tabLayout.setTabMode(TabLayout.MODE_FIXED);
else
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
private int calculateTabWidth(TabLayout tabLayout)
int tabWidth = 0;
for (int i = 0; i < tabLayout.getChildCount(); i++)
final View view = tabLayout.getChildAt(i);
view.measure(0, 0);
tabWidth += view.getMeasuredWidth();
return tabWidth;
【讨论】:
【参考方案18】:这是我的 2021 Kotlin 解决方案。 它实现了我从其他答案中无法做到的以下几点:
如果选项卡不多,它们会展开以填满整个宽度。 如果有很多选项卡,它们是可滚动的,因此它们不会被压扁。 即使 tabLayout 不是屏幕的全宽也能正常工作。为了实现这一点,我创建了一个 TabLayout
的子类,它覆盖了 onMeasure
class ScalableTabLayout : 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 onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
val tabLayout = getChildAt(0) as ViewGroup
val childCount = tabLayout.childCount
if (childCount > 0)
val widthPixels = MeasureSpec.getSize(widthMeasureSpec)
val tabMinWidth = widthPixels / childCount
var remainderPixels = widthPixels % childCount
tabLayout.forEachChild
if (remainderPixels > 0)
it.minimumWidth = tabMinWidth + 1
remainderPixels--
else
it.minimumWidth = tabMinWidth
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
然后在我的布局文件中使用它:
<com.package.name.ScalableTabLayout
android:id="@+id/tabs"
android:layout_
android:layout_
app:tabMaxWidth="0dp"
app:tabMode="scrollable" />
tabMaxWidth="0dp"
和 tabMode="scrollable"
都是必需的
【讨论】:
这是最好的解决方案!!谢谢! 这绝对是离合器,谢谢。请务必设置app:tabPaddingEnd="0dp"
和 app:tabPaddingStart="0dp"
否则您会在标签栏上看到一些来自未占像素的轻微时髦的滚动行为
@SameerJ 删除填充绝对不是我想要的。如果您像这样删除填充,则选项卡宽度只会包裹文本,因此所有选项卡将显示为一个连接。例如。三个选项卡“一”“二”“三”看起来像“OneTwoThree”。你指的是什么时髦的滚动?
@MattSmith 从极左到极右选择选项卡时会发生一些抖动,因为选项卡布局的大小仍然比屏幕宽度大几个像素,因为 onMeasure 计算以上不考虑该填充以上是关于当 tabMode 设置为“可滚动”时,TabLayout 不填充宽度的主要内容,如果未能解决你的问题,请参考以下文章
当我们将它的子项设置为列时,可拖动的可滚动工作表变得不可滚动