工具类代码: public class TabLayoutUtils { /** * 此方法必须在这个属性下生效app:tabGravity="center" * @param tabLayout */ public static void reflex(final TabLayout tabLayout) { tabLayout.post(new Runnable() { @Override public void run() { try { //拿到tabLayout的mTabStrip属性 LinearLayout mTabStrip = (LinearLayout) tabLayout.getChildAt(0); int dp10 = AppUtils.dip2px(tabLayout.getContext(), 10); for (int i = 0; i < mTabStrip.getChildCount(); i++) { View tabView = mTabStrip.getChildAt(i); //拿到tabView的mTextView属性 tab的字数不固定一定用反射取mTextView Field mTextViewField; try { mTextViewField = tabView.getClass().getDeclaredField("mTextView"); } catch (Exception e) { mTextViewField = tabView.getClass().getDeclaredField("textView"); //安卓28变量名变了 } mTextViewField.setAccessible(true); TextView mTextView = (TextView) mTextViewField.get(tabView); tabView.setPadding(0, 0, 0, 0); //因为我想要的效果是 字多宽线就多宽,所以测量mTextView的宽度 int width = 0; width = mTextView.getWidth(); if (width == 0) { mTextView.measure(0, 0); width = mTextView.getMeasuredWidth(); } //设置tab左右间距为10dp 注意这里不能使用Padding 因为源码中线的宽度是根据 tabView的宽度来设置的 LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams(); params.width = width; params.leftMargin = dp10; params.rightMargin = dp10; tabView.setLayoutParams(params); tabView.invalidate(); } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }); } /** * 设置tab的宽度 */ public static void setScaledTabLayout(final TabLayout tb_layout, final int leftDip, final int rightDip , final boolean hideTab) { ViewTreeObserver viewTreeObserver = tb_layout.getViewTreeObserver(); viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onGlobalLayout() { tb_layout.getViewTreeObserver().removeOnGlobalLayoutListener(this); LinearLayout mTabStrip = (LinearLayout) tb_layout.getChildAt(0); int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics()); int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics()); for (int i = 0; i < mTabStrip.getChildCount(); i++) { View child = mTabStrip.getChildAt(i); child.setPadding(0, 0, 0, 0); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1); params.leftMargin = left; params.rightMargin = right; child.setLayoutParams(params); child.invalidate(); } } }); } /** * 设置tab的下划线和文字一样宽度 * 此方法会忽视这个属性app:tabGravity="center" */ public static void setTabWidthSame(final TabLayout tabs) { ViewTreeObserver viewTreeObserver = tabs.getViewTreeObserver(); viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { tabs.getViewTreeObserver().removeOnGlobalLayoutListener(this); //拿到tabLayout的mTabStrip属性 LinearLayout mTabStrip = (LinearLayout) tabs.getChildAt(0); int totalWidth = mTabStrip.getMeasuredWidth(); int tabWidth = totalWidth/mTabStrip.getChildCount(); for (int i = 0; i < mTabStrip.getChildCount(); i++) { View child = mTabStrip.getChildAt(i); child.setPadding(0, 0, 0, 0); Field mTextViewField = null; int width = 0; try { try { mTextViewField = child.getClass().getDeclaredField("mTextView"); } catch (Exception e) { mTextViewField = child.getClass().getDeclaredField("textView"); //安卓28变量名变了 } mTextViewField.setAccessible(true); TextView mTextView = (TextView) mTextViewField.get(child); //因为我想要的效果是 字多宽线就多宽,所以测量mTextView的宽度 width = mTextView.getWidth(); if (width == 0) { mTextView.measure(0, 0); width = mTextView.getMeasuredWidth(); } } catch (Exception e) { e.printStackTrace(); } LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)child.getLayoutParams(); params.width = width; params.leftMargin = (tabWidth - width)/2; params.rightMargin = (tabWidth - width)/2; child.setLayoutParams(params); child.invalidate(); } } }); } }
自定义tab样式
mTbLayout.addTab(mTbLayout.newTab().setText(titles[0]), true); mTbLayout.addTab(mTbLayout.newTab().setText(titles[1]), false); mTbLayout.addTab(mTbLayout.newTab().setText(titles[2]), false); mTbLayout.addTab(mTbLayout.newTab().setText(titles[3]), false); for (int i = 0; i < titles.length; i++) { TabLayout.Tab tab = mTbLayout.getTabAt(i);//获得每一个tab FrameLayout box = (FrameLayout) LayoutInflater.from(mContext).inflate(R.layout.item_tab_layout, null); TextView textView = (TextView) box.findViewById(R.id.tab_text); textView.setText(titles[i]);//设置tab上的文字 tab.setCustomView(box);//给每一个tab设置view }
布局:
选择器: