Android TabLayout在tabMode设置为';可滚动';
我已将Android TabLayout在tabMode设置为';可滚动';,android,android-support-library,android-tablayout,Android,Android Support Library,Android 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"
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"/>
当屏幕宽度足够大以显示所有标签时(请参阅右边空白区域):
如果我将tabMode
更改为fixed,则会填充宽度,但选项卡太小。有什么合适的解决办法吗?我想这是实现你想要的最简单的方法
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();
}
}
}
我想这是实现你想要的最简单的方法
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();
}
}
}
试试这个变化
<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" />
尝试此更改
<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" />
我不在乎标签的宽度,但我在乎的是背景色没有扩展到全宽。所以我想到了这个解决方案,在它后面放了一个框架布局,背景颜色与标签相同
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/MyColor">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
style="@style/MyCustomTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
</FrameLayout>
我不在乎标签的宽度,但我在乎的是背景色没有扩展到全宽。所以我想到了这个解决方案,在它后面放了一个框架布局,背景颜色与标签相同
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/MyColor">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
style="@style/MyCustomTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
</FrameLayout>
而不是创建自定义的表格布局,或者创建更多的布局,这些布局仅作为后台表格布局的包装。试试这个
<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"/>
android:background=“@color/colorAccent”
app:tabGravity=“填充”
app:tabMode=“可滚动”/
这会将背景设置为“在表格布局后面”,而不是在每个选项卡后面设置背景。而不是创建自定义表格布局,并对其进行修改或创建更多布局,这些布局仅作为背景的包装。试试这个
<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"/>
android:background=“@color/colorAccent”
app:tabGravity=“填充”
app:tabMode=“可滚动”/
这会将背景设置为TableLayout后面,而不是在每个选项卡后面设置背景。@dtx12如果任何选项卡标题大于(measuredWidth/tabCount),则回答无效
对于这种情况,有我的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()
}
}
}
}
}
类FullWidthTabLayout:TabLayout{
构造函数(上下文:上下文?):超级(上下文)
构造函数(context:context?,attrs:AttributeSet?):super(context,attrs)
构造函数(context:context?,attrs:AttributeSet?,defStyleAttr:Int):super(context,attrs,defStyleAttr)
覆盖仅限乐趣的布局(更改为:布尔、l:Int、t:Int、r:Int、b:Int){
超级。在线布局(更改、l、t、r、b)
如果(更改){
val widths=mutableListOf()
对于(0..this.tabCount-1中的i){
添加(this.getTabAt(i)!!.customView!!.width)
}
if(widths.sum()equalPart}
var smallerWidths=widths.filter{it=equalPart}
smallerWidths=smallerWidths.filter{it
@dtx12如果任何选项卡标题大于(测量宽度/tabCount),则答案不起作用
对于这种情况,有我的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()
}
}
}
}
}
类FullWidthTabLayout:TabLayout{
构造函数(上下文:上下文?):超级(上下文)
构造函数(context:context?,attrs:AttributeSet?):super(context,attrs)
构造函数(context:context?,attrs:AttributeSet?,defStyleAttr:Int):super(context,attrs,defStyleAttr)
覆盖仅限乐趣的布局(更改为:布尔、l:Int、t:Int、r:Int、b:Int){
超级。在线布局(更改、l、t、r、b)
如果(更改){
val widths=mutableListOf()
对于(0..this.tabCount-1中的i){
添加(this.getTabAt(i)!!.customView!!.width)
}
if(widths.sum()equalPart}
var smallerWidths=widths.filter{it=equalPart}
smallerWidths=smallerWidths.filter{it
请使用这个,它肯定会解决这个问题
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed" />
请使用这个,它肯定会解决这个问题
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed" />
请检查此项,我认为它有效
公共类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);
}
}
private text查看mTxv\u主页、mTxv\u新闻、mTxv\u公告;
私人查看mView_主页、mView_新闻、mView_公告;
私人水平滚动视图hsv;
私人视页机视页机;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxv\U Home=(文本视图)findViewById(R.id.txv\U Home);
mTxv_新闻=(文本视图)findViewById(R.id.txv_新闻);
mTxv_公告=(文本视图)findViewById(R.id.txv_公告);
mView\u Home=(视图)findviewbyd(R.id.View\u Home);
mView_News=(View)findviewbyd(R.id.View_News);
mView\u公告=(查看)findviewbyd(R.id.View\u公告);
hsv=(水平滚动视图)findViewById(R.id.hsv);
看法
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.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
}
}
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:tabMode="scrollable"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/vpTabs"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabMode="scrollable"/>
</androidx.viewpager.widget.ViewPager>
app:tabMaxWidth="0dp"
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)
}
}
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;
}
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)
}
}