Android TabLayout控件

前言

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(内容尽可能充满)

    效果如下
    Android TabLayout控件_第1张图片

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

    效果如下
    Android TabLayout控件_第2张图片

  • 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控件

你可能感兴趣的:(Android,Material,Design)