尊重原创转载请注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵权必究!
在5.0以前我们想要实现像网易新闻客户端那样的的Tab可以有很多种选择:
比如古老的TabHost,3.0后ActionBar所提供的Tab,以及各种成熟的Tab开源控件等,都可以直接或间接地实现Tab的效果。然而,对于这样一种使用极多的控件,Android是不会放弃将它纳入麾下的打算的,于是乎在5.0后放出的design包中Android就厚颜无耻地推出了自家官方的TabLayout控件来方便地实现类似的效果。其实这玩意跟ActionBar的Tab没什么卵的区别,只是说它更符合谷歌自家的MD设计理念,不过在实际使用中这玩意略显蛋疼,废话不多说,我们还是直接切入主题,要想使用TabLayout你就得导入Android的design包:
<code class="hljs matlab has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">dependencies <span class="hljs-cell" style="box-sizing: border-box;">{ compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'com.android.support:design:22.2.0'</span> }</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
然后在你的布局里加入TabLayout就行了:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.design.widget.TabLayout android:id="@+id/ac_tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" />
</RelativeLayout>
这里需要注意的是design包中有些资源依赖于5.0,这是不是说我们就不能使用了呢,不是的,我们可以从AppCompat获得这些资源,将当前Activity的主题设置为Theme.AppCompat或其子类即可:
<activity android:name="tablayout.TabLayoutActivity" android:theme="@style/Theme.AppCompat" />
当然现在你运行不会看到任何东西,因为我们没往里面家东西嘛,与ActionBar类似的是TabLayout添加Tab也很方便,只需要调用其addTab方法即可:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TabLayoutActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> {</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(R.layout.ac_tab_layout); TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout); TabLayout.Tab tab1 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tab1"</span>); tabLayout.addTab(tab1); TabLayout.Tab tab2 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tab2"</span>); tabLayout.addTab(tab2); TabLayout.Tab tab3 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tab3"</span>); tabLayout.addTab(tab3); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>
运行效果如下:
非常简单,不过需要注意的是,这里的Tab类是TabLayout的一个静态内部类,并且其构造方法是包内可访问的,也就是说你无法在外部构造其实例,只能通过TabLayout的newTab方法:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TabLayout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">HorizontalScrollView</span> {</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ......省去很多代码......</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Tab</span> {</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ......省去很多代码......</span> Tab(TabLayout parent) { mPosition = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; mParent = parent; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Tab <span class="hljs-title" style="box-sizing: border-box;">newTab</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Tab(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ......省去很多代码......</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>
addTab方法有四个不同的实现,拿参数最多的addTab(Tab tab, int position, boolean setSelected)方法来说,第一个参数tab就不说了,第二个参数position表示当前Tab需要插入的位置,其值必须小于当前TabLayout所拥有的Tab总数减一,如果大于则会报出数组下标溢出异常,这点很好理解,最后的boolean参数setSelected与其名意义一样,表示当前添加的Tab是否为选中状态,拿上面代码中的第三个tab3来说,我们修改其代码如下:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab3 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tab3"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab3, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
运行后tab3默认就会是被选中状态:
TabLayout中的公共方法不算多,大多都很好理解,不过有一个方法爱哥表示对其极度不爽,setScrollPosition从名字上来看它是用来设置滚动位置的,大家注意我们的TabLayout中被选中的Tab下方不是有根线么,我们可以通过这个方法来设置它的位置。首先我们在布局中添加一个按钮:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.design.widget.TabLayout android:id="@+id/ac_tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:id="@+id/ac_tab_btn" android:layout_width="wrap_content" android:layout_centerInParent="true" android:layout_height="wrap_content" android:text="Move" />
</RelativeLayout>
然后呢为这个按钮绑定一个点击事件监听并在其中调用setScrollPosition方法:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Button btnAdd = (Button) findViewById(R.id.ac_tab_btn); btnAdd.setOnClickListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> View.OnClickListener() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) { tabLayout.setScrollPosition(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.5</span>F, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>); } });</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
setScrollPosition方法的三个参数根据官方文档给出的解释如下:
第一个参数表示当前Tab的位置,第二个参数是偏移值,从文档中看到该值的取值范围是0到1的一个半开区间,最后一个参数很好理解表示是否置移动后位置所对应的Tab为选中状态,打个比方,如果我从0移动到1的位置,如果updateSelectedText为true,那么1这个位置上的文本就会是一个选中状态。上面的代码中我们只是简单地让下方的横条从0的Tab位置移动到一个0.5F的位置,效果如下:
可能大家会觉得纳闷,这个0.5F是个吊毛意思,其实positionOffset这个参数是一个倍数值,它的计算逻辑有些复杂,从源码中看setScrollPosition的逻辑,大致分为两步:
public void setScrollPosition(int position, float positionOffset, boolean updateSelectedText) {
if (isAnimationRunning(getAnimation()))
return;
if (position < 0 || position >= mTabStrip.getChildCount())
return;
mTabStrip.setIndicatorPositionFromTabPosition(position, positionOffset);
scrollTo(calculateScrollXForTab(position, positionOffset), 0);
if (updateSelectedText)
setSelectedTabView(Math.round((float) position + positionOffset));
}
首先是
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mTabStrip<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setIndicatorPositionFromTabPosition</span>(position, positionOffset)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
这段的调用,其目的很简单,就是设置Tab下方的那个横条的位置,先是调用SlidingTabStrip的setIndicatorPositionFromTabPosition方法赋值:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> setIndicatorPositionFromTabPosition(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> positionOffset) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (TabLayout.isAnimationRunning(getAnimation())) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { mSelectedPosition = position; mSelectionOffset = positionOffset; updateIndicatorPosition(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>
然后又调用了updateIndicatorPosition来做具体的位置更新操作:
private void updateIndicatorPosition() {
View selectedTitle = getChildAt(mSelectedPosition);
int left;
int right;
if (selectedTitle != null && selectedTitle.getWidth() > 0) {
left = selectedTitle.getLeft();
right = selectedTitle.getRight();
if (mSelectionOffset > 0.0F && mSelectedPosition < getChildCount() - 1) {
View nextTitle = getChildAt(mSelectedPosition + 1);
left = (int) (mSelectionOffset * (float) nextTitle.getLeft() + (1.0F - mSelectionOffset) * (float) left);
right = (int) (mSelectionOffset * (float) nextTitle.getRight() + (1.0F - mSelectionOffset) * (float) right);
}
} else {
left = right = -1;
}
setIndicatorPosition(left, right);
}
首先是得到当前Tab左右的坐标值,然后尝试获取下一个Tab,如果有,那么根据相对位置计算最终的左右坐标,没有则不改变使用当前的左右坐标,这很好理解,最后通过setIndicatorPosition放啊分设置最终的横条位置:
<code class="hljs vbscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> void setIndicatorPosition(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">int</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">left</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">int</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">right</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">left</span> != mIndicatorLeft || <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">right</span> != mIndicatorRight) { mIndicatorLeft = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">left</span>; mIndicatorRight = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">right</span>; ViewCompat.postInvalidateOnAnimation(this); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
回到setScrollPosition方法中再看看第二步滚动TabLayout到指定位置:
<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;">scrollTo(<span class="hljs-function" style="box-sizing: border-box;">calculateScrollXForTab(position, positionOffset)</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
这一步在默认模式下不会被执行,TabLayout提供两种模式,一种是填充模式,也就是默认模式,表示TabLayout不可滚动,其宽度有一个最大值,所有的Tab则会挤在这个宽度中:
该模式的常量值为MODE_FIXED = 1,而我们可以通过TabLayout的setTabMode方法来设置其模式,这里我们将TabLayout的模式改为可滚动:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTabMode</span>(TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MODE</span>_SCROLLABLE)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
TabLayout.MODE_SCROLLABLE的常量值为0,这时候再看看效果:
这时候TabLayout变为可滚动而所有的Tab均显示完整。好我们现在回过头来看看
<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;">scrollTo(<span class="hljs-function" style="box-sizing: border-box;">calculateScrollXForTab(position, positionOffset)</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
这段代码,scrollTo这个方法相信大家做过滑动都不会太陌生,其会将当前视图滚动至指定的坐标位置,TabLayout是一个水平滚动视图,因此其Y坐标滚动至恒为0,而X坐标则通过calculateScrollXForTab这个方法来计算:
private int calculateScrollXForTab(int position, float positionOffset) {
if (mMode == 0) {
View selectedChild = mTabStrip.getChildAt(position);
View nextChild = position + 1 >= mTabStrip.getChildCount() ? null : mTabStrip.getChildAt(position + 1);
int selectedWidth = selectedChild == null ? 0 : selectedChild.getWidth();
int nextWidth = nextChild == null ? 0 : nextChild.getWidth();
return (int) (((float) selectedChild.getLeft() + (float) (selectedWidth + nextWidth) * positionOffset * 0.5F + (float) selectedChild.getWidth() * 0.5F) - (float) getWidth() * 0.5F);
} else {
return 0;
}
}
这里可以看到先做了一个判断,如果模式为填充也就是MODE_FIXED的情况下是不需要滚动的,只有当模式为MODE_SCROLLABLE时才会去滚动,X坐标的计算逻辑与updateIndicatorPosition方法中的计算逻辑类似,都是通过当前Tab与下一个Tab的相对关系来计算的。那么为什么爱哥会对setScrollPosition这个方法表示极度不爽呢?首先,这个方法调用的前提根据官方文档和源码来看是需要相邻的两个Tab共同计算的,打个比方,如果我想从第0个Tab跳转至第1个Tab那么我就可以这么干:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TabLayoutActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> {</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(R.layout.ac_tab_layout); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout); TabLayout.Tab tab1 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tab1"</span>); tabLayout.addTab(tab1); TabLayout.Tab tab2 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tab2"</span>); tabLayout.addTab(tab2); TabLayout.Tab tab3 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tab3"</span>); tabLayout.addTab(tab3); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); Button btnAdd = (Button) findViewById(R.id.ac_tab_btn); btnAdd.setOnClickListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> View.OnClickListener() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) { tabLayout.setScrollPosition(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>F, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); }); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
从第0个Tab开始,偏移值为一个单位,效果如下:
注意到这里的一个BUG没有,淡定,好戏在后头,大家想想虽说官方文档建议第二个参数的取值区间在0到1,但是我们完全可以考虑将该值设置大于1对吧,假设,仅仅是个假设,我们将其设为2,那么是否可以表示我们能直接从第0个Tab直接跳转到第2个Tab呢?答案好像是肯定的:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">btnAdd.setOnClickListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> View.OnClickListener() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) { tabLayout.setScrollPosition(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>F, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); });</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
运行效果如下:
是不是有点意外?但是注意,这种想法是错误的!!!这里之所以能够直接跳转到第2个Tab是因为在这个例子中我们的每个Tab宽度都是一样的,如果我们将Tab稍作修改:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab1 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Aige"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab1)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab2 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AigeStudio"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab2)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab3 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Studio"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab3)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
这时候你就会看到错误的计算显示了:
当然如果仅仅是相邻的滚动,这样做是没问题的,比如我们从第1个Tab滚动至第2个Tab:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TabLayoutActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> {</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(R.layout.ac_tab_layout); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout); TabLayout.Tab tab1 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Aige"</span>); tabLayout.addTab(tab1); TabLayout.Tab tab2 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AigeStudio"</span>); tabLayout.addTab(tab2, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); TabLayout.Tab tab3 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Studio"</span>); tabLayout.addTab(tab3); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); Button btnAdd = (Button) findViewById(R.id.ac_tab_btn); btnAdd.setOnClickListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> View.OnClickListener() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) { tabLayout.setScrollPosition(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>F, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); } }); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>
这样就没问题:
使用setScrollPosition的另一个问题是,滚动时Tab底部那个横条切换生硬,不知道大家注意到没,没注意到往上看之前的一些切换动图,非常生硬,然而如果我们用另外一种方式来做这种切换就显得很带感了,Tab类中提供了一个select方法来设置当前Tab被选中:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Tab { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ......省去很多代码......</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">select</span>() { mParent.selectTab(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ......省去很多代码......</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
这个方法所带来的效果就很不一样了,比如我们点击设置第三个Tab被选中:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TabLayoutActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> {</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(R.layout.ac_tab_layout); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout); TabLayout.Tab tab1 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Aige"</span>); tabLayout.addTab(tab1); TabLayout.Tab tab2 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AigeStudio"</span>); tabLayout.addTab(tab2); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> TabLayout.Tab tab3 = tabLayout.newTab().setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Studio"</span>); tabLayout.addTab(tab3); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); Button btnAdd = (Button) findViewById(R.id.ac_tab_btn); btnAdd.setOnClickListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> View.OnClickListener() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) { tab3.select(); } }); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>
效果是不是要动感的多呢:
从源码里可以看到select方法本质是调用了TabLayout中的selectTab方法:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> selectTab(Tab tab) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mSelectedTab == tab) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mSelectedTab != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mOnTabSelectedListener != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) mOnTabSelectedListener.onTabReselected(mSelectedTab); animateToTab(tab.getPosition()); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> newPosition = tab == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ? -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> : tab.getPosition(); setSelectedTabView(newPosition); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((mSelectedTab == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || mSelectedTab.getPosition() == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) && newPosition != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) setScrollPosition(newPosition, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>F, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> animateToTab(newPosition); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mSelectedTab != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && mOnTabSelectedListener != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) mOnTabSelectedListener.onTabUnselected(mSelectedTab); mSelectedTab = tab; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mSelectedTab != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && mOnTabSelectedListener != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) mOnTabSelectedListener.onTabSelected(mSelectedTab); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>
在该方法中比较重要的就是一个animateToTab方法的调用,该方法是产生动画效果的关键:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">animateToTab</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> newPosition) { clearAnimation(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (newPosition == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getWindowToken() == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || !ViewCompat.isLaidOut(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>)) { setScrollPosition(newPosition, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>F, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> startScrollX = getScrollX(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> targetScrollX = calculateScrollXForTab(newPosition, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>F); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> duration = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (startScrollX != targetScrollX) { ValueAnimatorCompat animator = ViewUtils.createAnimator(); animator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR); animator.setDuration(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>); animator.setIntValues(startScrollX, targetScrollX); animator.setUpdateListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ValueAnimatorCompat.AnimatorUpdateListener() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onAnimationUpdate</span>(ValueAnimatorCompat animator) { scrollTo(animator.getAnimatedIntValue(), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> TabLayout <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>$<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>$<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> = TabLayout.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(); } } ); animator.start(); } mTabStrip.animateIndicatorToPosition(newPosition, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>
如果你不需要设置Tab的一些监听的话那么完全可以通过反射的方式调用该方法滚动Tab至指定位置:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">public class TabLayoutActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.onCreate</span>(savedInstanceState)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> setContentView(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.layout</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ac</span>_tab_layout)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> final TabLayout tabLayout = (TabLayout) findViewById(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ac</span>_tab_layout)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab1 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Aige"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab1)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab2 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AigeStudio"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab2)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab3 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Studio"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab3)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab4 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Fuck You"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab4)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab5 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Some of bitch"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab5)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Tab</span> tab6 = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newTab</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setText</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Android"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addTab</span>(tab6)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTabMode</span>(TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MODE</span>_SCROLLABLE)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> Button btnAdd = (Button) findViewById(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.id</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ac</span>_tab_btn)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> btnAdd<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setOnClickListener</span>(new View<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.OnClickListener</span>() { @Override public void onClick(View v) { Class <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">clz</span> = tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getClass</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> try { Method animateToTab = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">clz</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getDeclaredMethod</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"animateToTab"</span>, new Class[]{int<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.class</span>})<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> animateToTab<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setAccessible</span>(true)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> animateToTab<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.invoke</span>(tabLayout, new Object[]{<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>})<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } catch (Exception e) { e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } } })<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li></ul>
运行效果如下:
Tab中还有些其它的方法比如setIcon设置图标、setTag设置一个Tag标签还有setCustomView设置一个自定义视图作为一个Tab等,这些都比较简单不多说了:
TabLayout还有个setTabGravity方法可以用来设置TabLayout的布局方式,该方法只有两个可选参数GRAVITY_FILL = 0和GRAVITY_CENTER = 1,默认值是GRAVITY_FILL,setTabGravity方法只有在Mode为MODE_FIXED的情况下才有用,比如现在我们有两个Tab且这两个Tab的宽度比TabLayout小,默认情况下Tab的显示如下:
如果我们将Gravity设置为GRAVITY_CENTER:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTabMode</span>(TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MODE</span>_FIXED)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTabGravity</span>(TabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.GRAVITY</span>_CENTER)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
那么它就会是这个样子:
不难理解吧。我们还可以通过setOnTabSelectedListener方法为Tab切换设置监听器,OnTabSelectedListener接口中有三个方法onTabSelected、onTabUnselected和onTabReselected,前两个都很好理解不多说,不过要注意的是onTabUnselected总会在onTabSelected前被触发,而onTabReselected则会在你重复点击Tab的时候会被触发。你也可以调用setTabTextColors方法来更改显示文本的颜色,setTabTextColors接收两个颜色值分别表示普通状态的颜色和选中状态的颜色,当然你也可以提供一个ColorStateList对象:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">tabLayout<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTabTextColors</span>(Color<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.RED</span>, Color<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.GREEN</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
效果如下:
这里要注意的是setTabTextColors方法必须在你添加Tab也就是调用addTab前调用,否则无效,这也是一个bug。还有一点是你无法通过代码的方式修改指示器也就是Tab下方的那根横线,因为那玩意由TabLayout的一个私有内部类SlidingTabStrip控制,其中的方法全TM是non-public的,不过值得欣慰的是你可以在xml中通过属性来改变它,当然上面我们说到的文本颜色也可以通过这种方式修改:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.design.widget.TabLayout android:id="@+id/ac_tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabIndicatorColor="#FFFFFF" app:tabSelectedTextColor="#00FF00" app:tabTextColor="#FF0000" />
</RelativeLayout>
效果如下:
大部分情况下TabLayout都不会单独使用,一般我们会配合ViewPager来实现一个完整的Tab切换效果,而TabLayout也提供了几个很简便的方法来与ViewPager进行关联交互,先在我们的布局里加一个ViewPager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<android.support.design.widget.TabLayout android:id="@+id/ac_tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager android:id="@+id/ac_tab_vp" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />
</LinearLayout>
然后,然后,然后还是看代码吧,TabLayout与ViewPager结合的逻辑有点绕:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TabLayoutActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> {</span> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 数据源 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String[] DATA = {<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AigeStudio"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Aige"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Studio"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Android"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Java"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Design"</span>}; <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(R.layout.ac_tab_layout); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取ViewPager</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> ViewPager viewPager = (ViewPager) findViewById(R.id.ac_tab_vp); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 构造一个TabPagerAdapter对象</span> TabPagerAdapter adapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TabPagerAdapter(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取ViewPager</span> TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置TabLayout模式</span> tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置从PagerAdapter中获取Tab</span> tabLayout.setTabsFromPagerAdapter(adapter); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置Tab的选择监听</span> tabLayout.setOnTabSelectedListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TabLayout.OnTabSelectedListener() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onTabSelected</span>(TabLayout.Tab tab) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 每当我们选择了一个Tab就将ViewPager滚动至对应的Page</span> viewPager.setCurrentItem(tab.getPosition(), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onTabUnselected</span>(TabLayout.Tab tab) { } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onTabReselected</span>(TabLayout.Tab tab) { } }); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 构造一个TabLayoutOnPageChangeListener对象</span> TabLayout.TabLayoutOnPageChangeListener listener = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TabLayout.TabLayoutOnPageChangeListener(tabLayout); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置ViewPager页面改变后的监听</span> viewPager.addOnPageChangeListener(listener); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置ViewPager的适配器</span> viewPager.setAdapter(adapter); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TabPagerAdapter</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">PagerAdapter</span> {</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getCount</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> DATA.length; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">isViewFromObject</span>(View view, Object object) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> view == object; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="box-sizing: border-box;">instantiateItem</span>(ViewGroup container, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) { TextView tvContent = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TextView(TabLayoutActivity.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); tvContent.setText(DATA[position]); tvContent.setGravity(Gravity.CENTER); container.addView(tvContent, ViewPager.LayoutParams.MATCH_PARENT, ViewPager.LayoutParams.WRAP_CONTENT); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> tvContent; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">destroyItem</span>(ViewGroup container, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position, Object object) { container.removeView((View) object); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> CharSequence <span class="hljs-title" style="box-sizing: border-box;">getPageTitle</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> DATA[position]; } } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li></ul>
运行效果如下:
其它的不多说,大家注意到我们的代码中并没有添加Tab的具体逻辑,但是从运行的结果来看却实实在在地把我们的Tab标题显示上去了,这里主要还是要归功于TabLayout的setTabsFromPagerAdapter方法,在该方法中TabLayout会通过PagerAdapter的getPageTitle方法获得Page中的标题并将其封装成一个Tab添加至TabLayout中:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setTabsFromPagerAdapter</span>(PagerAdapter adapter){ removeAllTabs(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> count = adapter.getCount(); i < count; i++) addTab(newTab().setText(adapter.getPageTitle(i))); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
这也是为什么我们会在PagerAdapter中重写getPageTitle方法返回数据的原因。同时我们为TabLayout设置了一个Tab选择监听,在Tab被选择后可以让滚动至对应的Page,这一步就完成了Tab到Page的事件绑定,那么当Page改变后又如何影响Tab呢?这时候我们就得为ViewPager添加一个PageChangeListener,而这个PageChangeListener当然你可以自己去实现,但是TabLayout提供了一个方便的实现类TabLayoutOnPageChangeListener,我们只需构造一个添加到ViewPager即可。是不是觉得逻辑有点乱?一会TabLayout一会ViewPager的,确实,我也觉的,不过TabLayout提供了一个更超级简便的方法setupWithViewPager来完成与ViewPager的结合,使用方法很简单,先把ViewPager的相关参数什么的设置好,比如Adapter什么的,然后直接调用TabLayout的setupWithViewPager方法设置即可:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(R.layout.ac_tab_layout); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取ViewPager</span> ViewPager viewPager = (ViewPager) findViewById(R.id.ac_tab_vp); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 构造一个TabPagerAdapter对象</span> TabPagerAdapter adapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TabPagerAdapter(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取ViewPager</span> TabLayout tabLayout = (TabLayout) findViewById(R.id.ac_tab_layout); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置TabLayout模式</span> tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置ViewPager的适配器</span> viewPager.setAdapter(adapter); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置ViewPager</span> tabLayout.setupWithViewPager(viewPager); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>
是不是感觉瞬间就简单了很多…………Fuck。好了TabLayout就啰嗦到这里,总结就一句话,这货一定是程序猿心情不好的时候写的,很多逻辑好奇葩啊有木有~~~~
Demo项目源码在Github可下载:AndroidViewDemo