下面,我们将PagerSlidingTabStrip使用到具体项目中。
dependencies {
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
}
最后实现逻辑代码。
package net.csdn.blog.ruancoder;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.Window;
import com.astuetz.PagerSlidingTabStrip;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
final PagerSlidingTabStrip tabStrip = (PagerSlidingTabStrip) findViewById(R.id.tab);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
Fragment[] fragments = {new NewsFragment(), new TechFragment(), new FinanceFragment(), new InternetFragment(), new
PhoneFragment()};
String[] titles = {"头条", "科技", "财经", "互联网", "手机"};
TabPagerAdapter adapter = new TabPagerAdapter(getSupportFragmentManager(), fragments, titles);
viewPager.setAdapter(adapter);
tabStrip.setViewPager(viewPager);
}
}
Activity中使用到的TabPagerAdapter类:
package net.csdn.blog.ruancoder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class TabPagerAdapter extends FragmentPagerAdapter {
private Fragment[] mFragments;
private String[] mTitles;
public TabPagerAdapter(FragmentManager fm, Fragment[] fragments, String[] titles) {
super(fm);
this.mFragments = fragments;
this.mTitles = titles;
}
@Override
public Fragment getItem(int position) {
return mFragments[position];
}
@Override
public int getCount() {
return mFragments.length;
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
}
package com.astuetz;
public class PagerSlidingTabStrip extends HorizontalScrollView {
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
// 这里省略了初始化各参数的代码
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
当我们获取到PagerSlidingTabStrip对象后,会调用它的setViewPager(ViewPager pager)方法。
在该方法内部,为ViewPager对象添加了滑动监听PageListener,并调用了notifyDataSetChanged()方法。
(4).notifyDataSetChanged()方法。
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
} else {
addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
scrollToChild(currentPosition, 0);
}
});
}
private class PageListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
// ......
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
// ......
}
@Override
public void onPageSelected(int position) {
// ......
}
}
这里重点是onPageScrolled()方法,当ViewPager在滑动过程中该方法不断被回调。在其中执行了2行代码,scrollToChild(),移动tab;invalidate(),触发View的onDraw()的调用。
(6).核心方法onDraw()。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// 默认在当前被选中的tab底部绘制滑动条
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// 如果正在滑动,在当前tab和下一个tab之间绘制滑动条
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
// 绘制滑动条,滑动条宽度为lineRight - lineLeft,高度为indicatorHeight
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// 绘制底部线条,线条宽度为PagerSlidingTabStrip的宽度,高度为underlineHeight
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// 在每个tab的右侧,绘制竖直分割线,分割线宽度为dividerWidth,高度为height - dividerPadding * 2
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
}
}