一、前言

在开发中,我们常常需要ViewPager结合Fragment一起使用,来实现多页签的切换效果。在以前,我们有以下一系列第三方库来帮我们实现:

而现在,我们可以使用Design support library库的TabLayout来实现了。

二、最终效果图

三、TabLayout的使用

1. 添加依赖

由于TabLayout在design包内,所以首先需要在app目录下的build.gradle中添加以下依赖:

<td class="code hljs bash">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

dependencies { compile ‘com.android.support:design:23.4.0’ }

    </td>
  </tr>
</table></figure> 

## 2. 创建布局 {#2-创建布局}

布局相当简单,只要添加TabLayout和ViewPager的布局即可:

### layout/activity_main.xml {#layout-activity-main-xml}<figure class="highlight xml"> 

<table>
  <tr>
    <td class="gutter">
      <div class="top-box hide">
        <div class="alert-info">
        </div>
      </div>
      
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
<span class="line">12</span>
<span class="line">13</span>
<span class="line">14</span>
<span class="line">15</span>
<span class="line">16</span>
<span class="line">17</span>
<span class="line">18</span>
<span class="line">19</span>
<span class="line">20</span>
<span class="line">21</span>
</td>

<td class="code hljs xml">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"

android:id=&quot;@+id/activity_main&quot;

android:layout_width=&quot;match_parent&quot;

android:layout_height=&quot;match_parent&quot;

android:orientation=&quot;vertical&quot;>

<android.support.design.widget.TabLayout
    android:id=&quot;@+id/tab_layout&quot;

    style=&quot;@style/TabLayoutStyle&quot;

    android:layout_width=&quot;match_parent&quot;

    android:layout_height=&quot;wrap_content&quot; />

<android.support.v4.view.ViewPager
    android:id=&quot;@+id/view_pager&quot;

    android:layout_width=&quot;match_parent&quot;

    android:layout_height=&quot;0dp&quot;

    android:layout_weight=&quot;1&quot;

    android:background=&quot;@android:color/white&quot;/>

" data-snippet-id=“ext.7e95e4aafc1011c962a1047c143edc4e” data-snippet-saved=“false” data-codota-status=“done”><?xml version=“1.0” encoding=“utf-8”?> <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android" xmlns:tools=http://schemas.android.com/tools" android:id=”@+id/activity_main” android:layout_width=“match_parent” android:layout_height=“match_parent” android:orientation=“vertical”>

<android.support.design.widget.TabLayout android:id="@+id/tab_layout" style="@style/TabLayoutStyle" android:layout_width=“match_parent” android:layout_height=“wrap_content” />

<android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width=“match_parent” android:layout_height=“0dp” android:layout_weight=“1” android:background="@android:color/white"/> </LinearLayout>

    </td>
  </tr>
</table></figure> 

还有其他的属性我习惯在style文件中设置:

### values/styles.xml {#values-styles-xml}<figure class="highlight xml"> 

<table>
  <tr>
    <td class="gutter">
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
</td>

<td class="code hljs xml">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

" data-snippet-id=“ext.3491be7a86f191eb534e54eaf54d5af9” data-snippet-saved=“false” data-codota-status=“done” style=“box-sizing: border-box; margin: 0px; display: block;"><!– TabLayout样式 –> <style name=“TabLayoutStyle” parent=“Widget.Design.TabLayout”> <item name=“tabIndicatorColor”>@color/colorPrimary</item> <item name=“tabSelectedTextColor”>@color/colorPrimary</item> <item name=“tabTextAppearance”>@style/TabTextAppearence</item> <item name=“tabPaddingEnd”>0dp</item> </style> <style name=“TabTextAppearence” parent=“TextAppearance.Design.Tab”> <item name=“android:textSize”>16sp</item> <item name=“textAllCaps”>false</item> </style>

    </td>
  </tr>
</table></figure> 

## 3. 创建Fragment {#3-创建Fragment}<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      <div class="top-box hide">
        <div class="alert-info">
        </div>
      </div>
      
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
<span class="line">12</span>
<span class="line">13</span>
<span class="line">14</span>
<span class="line">15</span>
<span class="line">16</span>
<span class="line">17</span>
<span class="line">18</span>
<span class="line">19</span>
<span class="line">20</span>
<span class="line">21</span>
<span class="line">22</span>
<span class="line">23</span>
<span class="line">24</span>
<span class="line">25</span>
<span class="line">26</span>
<span class="line">27</span>
<span class="line">28</span>
<span class="line">29</span>
<span class="line">30</span>
<span class="line">31</span>
<span class="line">32</span>
<span class="line">33</span>
<span class="line">34</span>
<span class="line">35</span>
<span class="line">36</span>
<span class="line">37</span>
<span class="line">38</span>
</td>

<td class="code hljs java">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

package com.sherlockshi.badgedtablayoutpractise;

import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;

/** * Author: SherlockShi * Date: 2016-11-01 16:31 * Description: */ public class PageFragment extends Fragment {

private static final String PAGE_NAME_KEY = “PAGE_NAME_KEY”;

public static PageFragment getInstance(String pageName) { Bundle args = new Bundle(); args.putString(PAGE_NAME_KEY, pageName); PageFragment pageFragment = new PageFragment(); pageFragment.setArguments(args);

return pageFragment; }

@Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_page, container, false); TextView textView = (TextView) view.findViewById(R.id.tv_page_name); textView.setText(getArguments().getString(PAGE_NAME_KEY));

return view; } }

    </td>
  </tr>
</table></figure> 

其中Fragment的布局`layout/fragment_page.xml`:<figure class="highlight xml"> 

<table>
  <tr>
    <td class="gutter">
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
</td>

<td class="code hljs xml">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

<TextView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"

android:id=&quot;@+id/tv_page_name&quot;

android:layout_width=&quot;match_parent&quot;

android:layout_height=&quot;match_parent&quot;

android:gravity=&quot;center&quot;/>

" data-snippet-id=“ext.370f013e7e86a8c7c5395e82126045d2” data-snippet-saved=“false” data-codota-status=“done”><?xml version=“1.0” encoding=“utf-8”?> <TextView xmlns:android=http://schemas.android.com/apk/res/android" xmlns:tools=http://schemas.android.com/tools" android:id=”@+id/tv_page_name” android:layout_width=“match_parent” android:layout_height=“match_parent” android:gravity=“center”/>

    </td>
  </tr>
</table></figure> 

## 4. ViewPager的适配器 {#4-ViewPager的适配器}<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      <div class="top-box hide">
        <div class="alert-info">
        </div>
      </div>
      
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
<span class="line">12</span>
<span class="line">13</span>
<span class="line">14</span>
<span class="line">15</span>
<span class="line">16</span>
<span class="line">17</span>
<span class="line">18</span>
<span class="line">19</span>
<span class="line">20</span>
<span class="line">21</span>
<span class="line">22</span>
<span class="line">23</span>
<span class="line">24</span>
<span class="line">25</span>
<span class="line">26</span>
<span class="line">27</span>
<span class="line">28</span>
<span class="line">29</span>
<span class="line">30</span>
<span class="line">31</span>
<span class="line">32</span>
<span class="line">33</span>
<span class="line">34</span>
<span class="line">35</span>
<span class="line">36</span>
<span class="line">37</span>
<span class="line">38</span>
<span class="line">39</span>
<span class="line">40</span>
<span class="line">41</span>
<span class="line">42</span>
<span class="line">43</span>
<span class="line">44</span>
<span class="line">45</span>
<span class="line">46</span>
<span class="line">47</span>
</td>

<td class="code hljs java">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

mFragmentList;

private List<String> mPageTitleList;

private List<Integer> mBadgeCountList;

public SimpleFragmentPagerAdapter(Context context,
                                  FragmentManager fm,

                                  List<Fragment> fragmentList,

                                  List<String> pageTitleList,

                                  List<Integer> badgeCountList)

{

    super(fm);

    this.mContext = context;

    this.mFragmentList = fragmentList;

    this.mPageTitleList = pageTitleList;

    this.mBadgeCountList = badgeCountList;

}

@Override

public Fragment getItem(int position) {

    return mFragmentList.get(position);

}

@Override

public int getCount() {

    return mFragmentList.size();

}

@Override

public CharSequence getPageTitle(int position) {

    return mPageTitleList.get(position);

}

}

" data-snippet-id=“ext.f1ef424453dae480ac7d46b6bf9a7cfc” data-snippet-saved=“false” data-codota-status=“done”>package com.sherlockshi.badgedtablayoutpractise;

import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter;

import java.util.List;

/** * Author: SherlockShi * Date: 2016-11-01 17:38 * Description: */ public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {

private Context mContext; private List<Fragment> mFragmentList; private List<String> mPageTitleList; private List<Integer> mBadgeCountList;

public SimpleFragmentPagerAdapter(Context context, FragmentManager fm, List<Fragment> fragmentList, List<String> pageTitleList, List<Integer> badgeCountList) { super(fm); this.mContext = context; this.mFragmentList = fragmentList; this.mPageTitleList = pageTitleList; this.mBadgeCountList = badgeCountList; }

@Override public Fragment getItem(int position) { return mFragmentList.get(position); }

@Override public int getCount() { return mFragmentList.size(); }

@Override public CharSequence getPageTitle(int position) { return mPageTitleList.get(position); } }

    </td>
  </tr>
</table></figure> 

## 5. 设置TabLayout {#5-设置TabLayout}<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      <div class="top-box hide">
        <div class="alert-info">
        </div>
      </div>
      
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
<span class="line">12</span>
<span class="line">13</span>
<span class="line">14</span>
<span class="line">15</span>
<span class="line">16</span>
<span class="line">17</span>
<span class="line">18</span>
<span class="line">19</span>
<span class="line">20</span>
<span class="line">21</span>
<span class="line">22</span>
<span class="line">23</span>
<span class="line">24</span>
<span class="line">25</span>
<span class="line">26</span>
<span class="line">27</span>
<span class="line">28</span>
<span class="line">29</span>
<span class="line">30</span>
<span class="line">31</span>
<span class="line">32</span>
<span class="line">33</span>
<span class="line">34</span>
<span class="line">35</span>
<span class="line">36</span>
<span class="line">37</span>
<span class="line">38</span>
<span class="line">39</span>
<span class="line">40</span>
<span class="line">41</span>
<span class="line">42</span>
<span class="line">43</span>
<span class="line">44</span>
<span class="line">45</span>
<span class="line">46</span>
<span class="line">47</span>
<span class="line">48</span>
<span class="line">49</span>
<span class="line">50</span>
<span class="line">51</span>
<span class="line">52</span>
<span class="line">53</span>
<span class="line">54</span>
<span class="line">55</span>
<span class="line">56</span>
<span class="line">57</span>
</td>

<td class="code hljs java">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

mPageTitleList = new ArrayList();

private List<Fragment> mFragmentList = new ArrayList<Fragment>();

private List<Integer> mBadgeCountList = new ArrayList<Integer>();

private SimpleFragmentPagerAdapter mPagerAdapter;

private TabLayout mTabLayout;

private ViewPager mViewPager;

@Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    initFragments();

    initView();

}

private void initFragments() {

    mPageTitleList.add(&quot;Tab1&quot;);

    mPageTitleList.add(&quot;Tab2&quot;);

    mPageTitleList.add(&quot;Tab3&quot;);

    mBadgeCountList.add(6);

    mBadgeCountList.add(16);

    mBadgeCountList.add(166);

    for (int i = 0; i < mPageTitleList.size(); i++) {

        mFragmentList.add(PageFragment.getInstance(mPageTitleList.get(i)));

    }

}

private void initView() {

    mTabLayout = (TabLayout) findViewById(R.id.tab_layout);

    mViewPager = (ViewPager) findViewById(R.id.view_pager);

    mPagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), mFragmentList, mPageTitleList);

    mViewPager.setAdapter(mPagerAdapter);

    mTabLayout.setupWithViewPager(mViewPager);

    initBadgeViews();

    setUpTabBadge();

}

}

" data-snippet-id=“ext.70f381a93ec7f8d5b4c401b6ed6c0077” data-snippet-saved=“false” data-codota-status=“done”>package com.sherlockshi.badgedtablayoutpractise;

import android.os.Bundle; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.view.ViewGroup;

import java.util.ArrayList; import java.util.List;

public class MainActivity extends AppCompatActivity {

private List<String> mPageTitleList = new ArrayList<String>(); private List<Fragment> mFragmentList = new ArrayList<Fragment>(); private List<Integer> mBadgeCountList = new ArrayList<Integer>();

private SimpleFragmentPagerAdapter mPagerAdapter; private TabLayout mTabLayout; private ViewPager mViewPager;

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

initFragments(); initView(); }

private void initFragments() { mPageTitleList.add(“Tab1”); mPageTitleList.add(“Tab2”); mPageTitleList.add(“Tab3”);

mBadgeCountList.add(6); mBadgeCountList.add(16); mBadgeCountList.add(166);

for (int i = ; i < mPageTitleList.size(); i++) { mFragmentList.add(PageFragment.getInstance(mPageTitleList.get(i))); } }

private void initView() { mTabLayout = (TabLayout) findViewById(R.id.tab_layout); mViewPager = (ViewPager) findViewById(R.id.view_pager);

mPagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), mFragmentList, mPageTitleList); mViewPager.setAdapter(mPagerAdapter); mTabLayout.setupWithViewPager(mViewPager);

initBadgeViews(); setUpTabBadge(); } }

    </td>
  </tr>
</table></figure> 

# 四、设置角标 {#四、设置角标}

## 1. 添加角标Badge {#1-添加角标Badge}

添加角标的关键代码只需要一行:<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      ```
<span class="line">1</span>
</td>

<td class="code hljs css">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

mBadgeViews.get(i).setTargetView(((ViewGroup) mTabLayout.getChildAt()).getChildAt(i));

    </td>
  </tr>
</table></figure> 

完整代码只需要在设置完TabLayout和ViewPager后,遍历每一个Tab,为Tab添加角标:<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
</td>

<td class="code hljs cs">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

private void setUpTabBadge() { for (int i = ; i < mFragmentList.size(); i++) { mBadgeViews.get(i).setTargetView(((ViewGroup) mTabLayout.getChildAt()).getChildAt(i)); mBadgeViews.get(i).setText(formatBadgeNumber(mBadgeCountList.get(i))); } }

    </td>
  </tr>
</table></figure> 

## 2. 更新角标 {#2-更新角标}

在需要更新角标的地方,只要调用以下方法就可实现:<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      ```
<span class="line">1</span>
<span class="line">2</span>
</td>

<td class="code hljs bash">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

mBadgeCountList.set(1, count++); setUpTabBadge();

    </td>
  </tr>
</table></figure> 

以上,就可以轻松地为TabLayout添加角标,并处理角标的更新了。

# 五、问题 {#五、问题}

## 1. 重复选中的状态 {#1-重复选中的状态}

但是如果需要更新角标,那么在`更新角标后`,再点击另一个Tab,会出现`上一个Tab`和`当前Tab`都是选中状态(如下图的Tab1和Tab2):

![](http://7xlpfl.com1.z0.glb.clouddn.com/sherlockshi/2016-11-03-Snip20161103_6.png) 

## 2. 角标位置不可控 {#2-角标位置不可控}

而且如上图所示,角标的位置不好控制,有的离文字很近,有的离得很远,无法精确控制。

# 六、最实用的TabLayout加角标方法 {#六、最实用的TabLayout加角标方法}

## 1. 添加getTabItemView()方法 {#1-添加getTabItemView-方法}

在重写的FragmentPagerAdapter中添加自定义Tab布局方法:<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      <div class="top-box hide">
        <div class="alert-info">
        </div>
      </div>
      
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
<span class="line">12</span>
<span class="line">13</span>
<span class="line">14</span>
<span class="line">15</span>
</td>

<td class="code hljs cs">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

public View getTabItemView(int position) { View view = LayoutInflater.from(mContext).inflate(R.layout.tab_layout_item, null); TextView textView = (TextView) view.findViewById(R.id.textview); textView.setText(mPageTitleList.get(position));

View target = view.findViewById(R.id.badgeview_target);

BadgeView badgeView = new BadgeView(mContext); badgeView.setTargetView(target); badgeView.setBadgeMargin(, 6, 10, ); badgeView.setTextSize(10); badgeView.setText(formatBadgeNumber(mBadgeCountList.get(position)));

return view; }

    </td>
  </tr>
</table></figure> 

对应的自定义布局为:<figure class="highlight"> 

<table>
  <tr>
    <td class="gutter">
      <div class="top-box hide">
        <div class="alert-info">
        </div>
      </div>
      
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
<span class="line">12</span>
<span class="line">13</span>
<span class="line">14</span>
<span class="line">15</span>
<span class="line">16</span>
<span class="line">17</span>
<span class="line">18</span>
<span class="line">19</span>
<span class="line">20</span>
<span class="line">21</span>
<span class="line">22</span>
<span class="line">23</span>
<span class="line">24</span>
<span class="line">25</span>
<span class="line">26</span>
<span class="line">27</span>
<span class="line">28</span>
<span class="line">29</span>
</td>

<td class="code hljs xml">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools=&quot;http://schemas.android.com/tools&quot;

android:layout_width=&quot;match_parent&quot;

android:layout_height=&quot;wrap_content&quot;

android:orientation=&quot;horizontal&quot;>

<!-- LinearLayout的Height必须为wrap_content,如果为match_parent,那么在第二次加载Badge的时候,Tab布局会出现问题 -->

<View

    android:layout_width=&quot;0dp&quot;

    android:layout_weight=&quot;1&quot;

    android:layout_height=&quot;wrap_content&quot;/>

<TextView

    android:id=&quot;@+id/textview&quot;

    android:layout_width=&quot;wrap_content&quot;

    android:layout_height=&quot;wrap_content&quot;

    android:layout_gravity=&quot;center&quot;

    android:layout_marginLeft=&quot;-30dp&quot;

    android:textColor=&quot;@color/tab_text_color_selector&quot;/>

<View

    android:id=&quot;@+id/badgeview_target&quot;

    android:layout_width=&quot;0dp&quot;

    android:layout_weight=&quot;1&quot;

    android:layout_height=&quot;40dp&quot;

    android:layout_marginLeft=&quot;4dp&quot;

    android:layout_gravity=&quot;center&quot;/>

" data-snippet-id=“ext.89ae1cafa820c0153ee8e464b7820214” data-snippet-saved=“false” data-codota-status=“done”><?xml version=“1.0” encoding=“utf-8”?> <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android" xmlns:tools=http://schemas.android.com/tools" android:layout_width=“match_parent” android:layout_height=“wrap_content” android:orientation=“horizontal”> <!– LinearLayout的Height必须为wrap_content,如果为match_parent,那么在第二次加载Badge的时候,Tab布局会出现问题 –>

<View android:layout_width=“0dp” android:layout_weight=“1” android:layout_height=“wrap_content”/>

<TextView android:id=”@+id/textview” android:layout_width=“wrap_content” android:layout_height=“wrap_content” android:layout_gravity=“center” android:layout_marginLeft="-30dp” android:textColor="@color/tab_text_color_selector"/>

<View android:id="@+id/badgeview_target" android:layout_width=“0dp” android:layout_weight=“1” android:layout_height=“40dp” android:layout_marginLeft=“4dp” android:layout_gravity=“center”/> </LinearLayout>

    </td>
  </tr>
</table></figure> 

## 2. 设置自定义布局 {#2-设置自定义布局}<figure class="highlight java"> 

<table>
  <tr>
    <td class="gutter">
      <div class="top-box hide">
        <div class="alert-info">
        </div>
      </div>
      
      ```
<span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
<span class="line">11</span>
<span class="line">12</span>
<span class="line">13</span>
<span class="line">14</span>
<span class="line">15</span>
<span class="line">16</span>
<span class="line">17</span>
<span class="line">18</span>
<span class="line">19</span>
<span class="line">20</span>
</td>

<td class="code hljs coffeescript">
  <div class="top-box hide">
    <div class="alert-info">
    </div>
  </div>
  
  ```

private void setUpTabBadge() { for (int i = ; i < mFragmentList.size(); i++) { TabLayout.Tab tab = mTabLayout.getTabAt(i);

// 更新Badge前,先remove原来的customView,否则Badge无法更新 View customView = tab.getCustomView(); if (customView != null) { ViewParent parent = customView.getParent(); if (parent != null) { ((ViewGroup) parent).removeView(customView); } }

// 更新CustomView tab.setCustomView(mPagerAdapter.getTabItemView(i)); }

// 需加上以下代码,不然会出现更新Tab角标后,选中的Tab字体颜色不是选中状态的颜色 mTabLayout.getTabAt(mTabLayout.getSelectedTabPosition()).getCustomView().setSelected(true); }

    </td>
  </tr>
</table></figure> 

上面的示例会有两个坑:

  * 一个坑是每次为TabLayout添加Badge后,会出现Tab的字体颜色不是选中状态的颜色,需要手动设置Tab为选中状态,可以参考上面的第19行代码解决,这应该是TabLayout的一个Bug;
  * 另一个坑是如果每次更新Badge的时候,直接重新tab.setCustomView的话,会出现Badge不更新,解决办法是先移除之前的自定义布局,然后再重新设置布局,具体可参考第6-12行代码解决。

# 七、总结 {#七、总结}

以上是自己在使用TabLayout的过程中发现的一些问题及解决办法,如果大家有更好的解决方法,或者还有别的坑,欢迎留言。

当然,大家也可以直接使用第三方控件来实现以上功能,现在主流的几个控件也都做得很好,也很省心。

项目代码已共享到Github:[BadgedTabLayoutPractise](https://github.com/SherlockShi/BadgedTabLayoutPractise)

# 八、参考资料 {#八、参考资料}

[android design library提供的TabLayout的用法](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0731/3247.html)

[Google Play Style Tabs using TabLayout](https://guides.codepath.com/android/Google-Play-Style-Tabs-using-TabLayout#design-support-library)

[Android Tablayout tabs with notification badge like whatsApp](http://stackoverflow.com/questions/31968162/android-tablayout-tabs-with-notification-badge-like-whatsapp)

💬 评论

``` 1 2 3 4 ```