Android TabLayout控件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chennai1101/article/details/84229003

相关文章
Android Snackbar控件
Android FloatingActionButton控件
Android Toolbar控件
Android AppBarLayout控件
Android CollapsingToolbarLayout控件
Android CardView控件
Android SlidingPaneLayout和DrawerLayout控件
Android TabLayout控件

前言

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

1. TabLayout类

布局文件

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:background="@color/white"/>

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

    效果如下
    在这里插入图片描述

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

    效果如下
    在这里插入图片描述

  • tabBackground,背景

  • tabContentStart,相对起始位置tab的Y轴偏移量

  • tabPadding,tab的内边距

  • tabPaddingStart,tab的左侧内边距

  • tabPaddingEnd,tab的右侧内边距

  • tabPaddingTop,tab的顶部内边距

  • tabPaddingBottom,tab的底部内边距

  • tabMaxWidth,tab选项卡的最大宽度

  • tabMinWidth,tab选项卡的最小宽度

3. TabLayout主要方法

  • addTab,向此布局添加选项卡
  • addView,添加子视图
  • addOnTabSelectedListener,添加监听器
  • newTab,创建一个新的tab
  • setTabTextColors,设置用于选项卡的不同状态的文本颜色
  • setSelectedTabIndicatorColor,设置选中的tab的指示器颜色
  • setSelectedTabIndicatorHeight,设置选中的tab的指示器的高度
  • setTabGravity,设置TabLayout的布局方式
  • setTabMode,设置tab选项卡的行为模式
  • setupWithViewPager,将TabLayout与ViewPager链接在一起

4. 自定义控件

  • 在配置文件中指定TabItem

      <android.support.design.widget.TabLayout
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_gravity="center_horizontal"
          android:background="@color/white">
          <android.support.design.widget.TabItem
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="tab1"/>
    
          <android.support.design.widget.TabItem
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="tab2"
              android:icon="@mipmap/ic_launcher"/>
    
          <android.support.design.widget.TabItem
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout="@layout/layout_tab_item1"/>
    
      </android.support.design.widget.TabLayout>
    
  • 调用Tab.setCustomView方法

      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方法

      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方法会调用addViewInternal方法,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();
          }
      }
    

猜你喜欢

转载自blog.csdn.net/chennai1101/article/details/84229003