TabLayout
是5.0版本出现的控件,显示水平方向的tab
页。需要添加Design
依赖库,并且使用Theme.AppCompat
主题。
布局文件
利用addTab(Tab)
和newTab()
方法添加tab页
TabLayout tabLayout = findViewById(R.id.tab_layout1);
tabLayout.addTab(tabLayout.newTab().setText("tab1"));
tabLayout.addTab(tabLayout.newTab().setText("tab2"));
tabLayout.addTab(tabLayout.newTab().setText("tab3"));
tabSelectedTextColor
,改变选中字体的颜色
tabTextColor
,未选中字体的颜色
tabTextAppearance
,字体大小
app:tabSelectedTextColor="#FFFF8800"
app:tabTextColor="#FFCCCCCC"
app:tabTextAppearance="@style/tabLayoutTextAppearance"
tabIndicatorColor
,指示器下标的颜色
tabIndicatorHeight
,指示器下标的高度
app:tabIndicatorColor="#FFFF8800"
app:tabIndicatorHeight="4dp"
tabGravity
,内容显示方式center
(内容居中显示)和fill
(内容尽可能充满)
tabMode
,tab
选项卡的行为模式,fixed
(tab固定)和scrollable
(tab可滑动)
tabBackground
,背景
tabContentStart
,相对起始位置tab
的Y
轴偏移量
tabPadding
,tab
的内边距
tabPaddingStart
,tab
的左侧内边距
tabPaddingEnd
,tab
的右侧内边距
tabPaddingTop
,tab
的顶部内边距
tabPaddingBottom
,tab
的底部内边距
tabMaxWidth
,tab
选项卡的最大宽度
tabMinWidth
,tab
选项卡的最小宽度
addTab(Tab)
,向此布局添加选项卡addView(View)
,添加子视图addOnTabSelectedListener(OnTabSelectedListener)
,添加监听器newTab()
,创建一个新的tab
setTabTextColors(int, int)
,设置用于选项卡的不同状态的文本颜色setSelectedTabIndicatorColor(int)
,设置选中的tab
的指示器颜色setSelectedTabIndicatorHeight(int)
,设置选中的tab
的指示器的高度setTabGravity(int)
,设置TabLayout
的布局方式setTabMode(int)
,设置tab
选项卡的行为模式setupWithViewPager(ViewPager, boolean)
,将TabLayout
与ViewPager
绑定在一起在配置文件中指定TabItem
调用Tab.setCustomView(int)
方法
tabLayout.addTab(tabLayout.newTab().setCustomView(R.layout.layout_tab_item2));
TabLayout.newTab()
方法
public Tab newTab() {
// sTabPool是一个数据池,保存Tab
Tab tab = sTabPool.acquire();
if (tab == null) {
tab = new Tab();
}
tab.mParent = this;
// createTabView 方法创建一个`TabView`
tab.mView = createTabView(tab);
return tab;
}
private TabView createTabView(@NonNull final Tab tab) {
// mTabViewPool同样是个数据池,用来保存TabView
TabView tabView = mTabViewPool != null ? mTabViewPool.acquire() : null;
if (tabView == null) {
tabView = new TabView(getContext());
}
// 设置tab内容
tabView.setTab(tab);
tabView.setFocusable(true);
tabView.setMinimumWidth(getTabMinWidth());
return tabView;
}
TabView
继承LinearLayout
public TabView(Context context) {
super(context);
if (mTabBackgroundResId != 0) {
ViewCompat.setBackground(
this, AppCompatResources.getDrawable(context, mTabBackgroundResId));
}
ViewCompat.setPaddingRelative(this, mTabPaddingStart, mTabPaddingTop,
mTabPaddingEnd, mTabPaddingBottom);
setGravity(Gravity.CENTER);
setOrientation(VERTICAL);
setClickable(true);
ViewCompat.setPointerIcon(this,
PointerIconCompat.getSystemIcon(getContext(), PointerIconCompat.TYPE_HAND));
}
void setTab(@Nullable final Tab tab) {
if (tab != mTab) {
mTab = tab;
update();
}
}
final void update() {
final Tab tab = mTab;
// 是否是自定义View
final View custom = tab != null ? tab.getCustomView() : null;
if (custom != null) {
final ViewParent customParent = custom.getParent();
if (customParent != this) {
if (customParent != null) {
((ViewGroup) customParent).removeView(custom);
}
addView(custom);
}
mCustomView = custom;
// 设置默认不可见
if (mTextView != null) {
mTextView.setVisibility(GONE);
}
if (mIconView != null) {
mIconView.setVisibility(GONE);
mIconView.setImageDrawable(null);
}
mCustomTextView = (TextView) custom.findViewById(android.R.id.text1);
if (mCustomTextView != null) {
mDefaultMaxLines = TextViewCompat.getMaxLines(mCustomTextView);
}
mCustomIconView = (ImageView) custom.findViewById(android.R.id.icon);
} else {
// We do not have a custom view. Remove one if it already exists
if (mCustomView != null) {
removeView(mCustomView);
mCustomView = null;
}
mCustomTextView = null;
mCustomIconView = null;
}
// 如果没有自定义View,使用默认ImageView和TextView
if (mCustomView == null) {
// If there isn't a custom view, we'll us our own in-built layouts
if (mIconView == null) {
ImageView iconView = (ImageView) LayoutInflater.from(getContext())
.inflate(R.layout.design_layout_tab_icon, this, false);
addView(iconView, 0);
mIconView = iconView;
}
if (mTextView == null) {
TextView textView = (TextView) LayoutInflater.from(getContext())
.inflate(R.layout.design_layout_tab_text, this, false);
addView(textView);
mTextView = textView;
mDefaultMaxLines = TextViewCompat.getMaxLines(mTextView);
}
TextViewCompat.setTextAppearance(mTextView, mTabTextAppearance);
if (mTabTextColors != null) {
mTextView.setTextColor(mTabTextColors);
}
updateTextAndIcon(mTextView, mIconView);
} else {
// Else, we'll see if there is a TextView or ImageView present and update them
if (mCustomTextView != null || mCustomIconView != null) {
updateTextAndIcon(mCustomTextView, mCustomIconView);
}
}
// Finally update our selected state
setSelected(tab != null && tab.isSelected());
}
TabLayout.addTab(Tab, int, boolean)
方法
public void addTab(@NonNull Tab tab, int position, boolean setSelected) {
if (tab.mParent != this) {
throw new IllegalArgumentException("Tab belongs to a different TabLayout.");
}
configureTab(tab, position);
addTabView(tab);
if (setSelected) {
tab.select();
}
}
// 配置Tab
private void configureTab(Tab tab, int position) {
tab.setPosition(position);
mTabs.add(position, tab);
final int count = mTabs.size();
for (int i = position + 1; i < count; i++) {
mTabs.get(i).setPosition(i);
}
}
private void addTabView(Tab tab) {
final TabView tabView = tab.mView;
mTabStrip.addView(tabView, tab.getPosition(), createLayoutParamsForTabs());
}
TabLayout.addView(View)
方法会调用addViewInternal(View)
方法,child
必须是TabItem
类型。
private void addViewInternal(final View child) {
if (child instanceof TabItem) {
addTabFromItemView((TabItem) child);
} else {
throw new IllegalArgumentException("Only TabItem instances can be added to TabLayout");
}
}
private void addTabFromItemView(@NonNull TabItem item) {
final Tab tab = newTab();
if (item.mText != null) {
// 会调用TabView.update修改
tab.setText(item.mText);
}
if (item.mIcon != null) {
// 会调用TabView.update修改
tab.setIcon(item.mIcon);
}
if (item.mCustomLayout != 0) {
// 会调用TabView.update修改
tab.setCustomView(item.mCustomLayout);
}
if (!TextUtils.isEmpty(item.getContentDescription())) {
tab.setContentDescription(item.getContentDescription());
}
addTab(tab);
}
TabItem
类,可以指定text
和icon
,也可以自定义layout
。
public final class TabItem extends View {
final CharSequence mText;
final Drawable mIcon;
final int mCustomLayout;
public TabItem(Context context) {
this(context, null);
}
public TabItem(Context context, AttributeSet attrs) {
super(context, attrs);
final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,
R.styleable.TabItem);
mText = a.getText(R.styleable.TabItem_android_text);
mIcon = a.getDrawable(R.styleable.TabItem_android_icon);
mCustomLayout = a.getResourceId(R.styleable.TabItem_android_layout, 0);
a.recycle();
}
}
相关文章
Android Snackbar控件
Android FloatingActionButton控件
Android Toolbar控件
Android AppBarLayout控件
Android CollapsingToolbarLayout控件
Android CardView控件
Android SlidingPaneLayout和DrawerLayout控件
Android TabLayout控件