前言

TabLayout是5.0版本出现的控件,显示水平方向的tab页。需要添加Design依赖库,并且使用Theme.AppCompat主题。

1. TabLayout类

布局文件

利用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"));

效果如下

2. 主要参数

  • tabSelectedTextColor,改变选中字体的颜色

  • tabTextColor,未选中字体的颜色

  • tabTextAppearance,字体大小

      app:tabSelectedTextColor="#FFFF8800"  app:tabTextColor="#FFCCCCCC"  app:tabTextAppearance="@style/tabLayoutTextAppearance"

    效果如下

  • tabIndicatorColor,指示器下标的颜色

  • tabIndicatorHeight,指示器下标的高度

      app:tabIndicatorColor="#FFFF8800"  app:tabIndicatorHeight="4dp"

    效果如下

  • tabGravity,内容显示方式center(内容居中显示)和fill(内容尽可能充满)

    效果如下

  • tabModetab选项卡的行为模式,fixed(tab固定)和scrollable(tab可滑动)

    效果如下

  • tabBackground,背景

  • tabContentStart,相对起始位置tabY轴偏移量

  • tabPaddingtab的内边距

  • tabPaddingStarttab的左侧内边距

  • tabPaddingEndtab的右侧内边距

  • tabPaddingToptab的顶部内边距

  • tabPaddingBottomtab的底部内边距

  • tabMaxWidthtab选项卡的最大宽度

  • tabMinWidthtab选项卡的最小宽度

3. TabLayout主要方法

  • 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),将TabLayoutViewPager绑定在一起

4. 自定义TabItem

  • 在配置文件中指定TabItem

                          
  • 调用Tab.setCustomView(int)方法

      tabLayout.addTab(tabLayout.newTab().setCustomView(R.layout.layout_tab_item2));

效果如下

5. TabLayout代码分析

  • 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类,可以指定texticon,也可以自定义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控件

更多相关文章

  1. android M 如何获取设置应用通知开关状态
  2. 事件分发机制(View)
  3. Android中EditText实现不可编辑解决办法
  4. Android(安卓)Studio使用笔记
  5. Android简易实战教程--第一话《最简单的计算器》
  6. Android4.4 及以下TextView,Button等控件使用矢量图报错
  7. Android(安卓)WIFI检测与设置
  8. Android控件系列之相册Gallery&Adapter适配器入门&控件缩放动画
  9. Android之自定义各种控件

随机推荐

  1. freetds简介、安装、配置及使用介绍
  2. android ViewModelProviders被弃用解决方
  3. [Android]设置Activity为全屏显示的两种
  4. Android系统属性SystemProperties分析
  5. Mac 安装 Android(安卓)Studio 以及 Andr
  6. 修改android日期格式
  7. ListView去掉中间的分割线和设置Item之间
  8. unsupported dynamic reloc R_ARM_REL32
  9. Ubuntu下查找.android/avd
  10. react-native-s-alipay -- React Native