自定义ScrollingTabs结合ViewPager实现指引的效果。
原理:
由于ScrollingTabs
即可以点击又可以实现左右滑动,首先想到的就是继承HorizontalScrollView
来实现滑动,至于点击的实现需要通过对View
设置点击。
通过对ViewPager
设置OnPageChangeListener
来监听页面变化,从而实现对ScrollingTabs
的改变,而在每个Tab
上设置
点击事件,当点击的时候就去设置ViewPager
的当前页面
- 继承HorizontalScrollView,并且添加一个水平方向的线性布局,作为Tab的父布局
public class ScrollingTabs extends HorizontalScrollView {
private LinearLayout mContainer;
public ScrollingTabs(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public ScrollingTabs(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ScrollingTabs(Context context) {
super(context);
init(context);
}
private void init(Context context) {
this.setHorizontalScrollBarEnabled(false);
this.setHorizontalFadingEdgeEnabled(false);
mContainer = new LinearLayout(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.MATCH_PARENT);
mContainer.setLayoutParams(params);
mContainer.setOrientation(LinearLayout.HORIZONTAL);
addView(mContainer);
}
- 提供接口供调用者设置每个Tab的视图。
public interface TabAdapter {
/**
* 每个Tab的视图
*/
public View getView(int position);
/**
* Tab之间的分割线
*/
public View getSeparator();
}
- 暴露方法,初始化Tab。
public void setTabAdapter(TabAdapter adapter) {
this.mTabAdapter = adapter;
initTabView();
}
public void setViewPager(ViewPager pager) {
this.mViewPager = pager;
mViewPager.setOnPageChangeListener(this);
initTabView();
}
/**
* 必须等到ViewPager和TabAdapter都设置完成后才可以调用
*/
private void initTabView() {
if (mViewPager != null && mTabAdapter != null) {
//清空父布局,保险起见
mContainer.removeAllViews();
//根据ViewPager的页数去设置Tab
for (int i = 0; i < mViewPager.getAdapter().getCount(); i++) {
final View tab = mTabAdapter.getView(i);
tab.setTag(i);
mContainer.addView(tab);
// Segmentation view
if (mTabAdapter.getSeparator() != null
&& i != mViewPager.getAdapter().getCount() - 1) {
//Tabs之间使用分割线
isUseSeperator = true;
mContainer.addView(mTabAdapter.getSeparator());
}
// 对每个Tab设置点击事件
tab.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int index = (Integer) tab.getTag();
if (mTabClickListener != null) {
//暴露接口
mTabClickListener.onClick(index);
} else {
if (mViewPager.getCurrentItem() == index) {
//如果当前ViewPager已经显示到了该Tab也,就直接让其选中
selectTab(index);
} else {
//当前ViewPager并没有显示该Tab页,要让ViewPager去显示相应的Tab页
mViewPager.setCurrentItem(index, true);
}
}
}
});
}
// 初始化时核对一下Tab
selectTab(mViewPager.getCurrentItem());
}
}
- selectTab的实现,选中相应的Tab,并且实现滑动到屏幕中间位置
private void selectTab(int position) {
if (!isUseSeperator) {
//没有分割线
for (int i = 0; i < mContainer.getChildCount(); i++) {
View tab = mContainer.getChildAt(i);
tab.setSelected(i == position);
}
} else {
//有分割线
for (int i = 0, pos = 0; i < mContainer.getChildCount(); i += 2, pos++) {
View tab = mContainer.getChildAt(i);
tab.setSelected(pos == position);
}
}
//得到当前的Tab
View selectedView = null;
if (!isUseSeperator) {
selectedView = mContainer.getChildAt(position);
} else {
selectedView = mContainer.getChildAt(position * 2);
}
int tabWidth = selectedView.getMeasuredWidth();
int tabLeft = selectedView.getLeft();
//距离左边屏幕的位置加上该Tab宽度的一半正好是该Tab中心点的位置。我们需要让该Tab的中心点移动到屏幕的中心点。
int distance = (tabLeft + tabWidth / 2) - mWindowWidth / 2;
//移动
smoothScrollTo(distance, this.getScrollY());
}
- 邮箱 :[email protected]
- Good Luck!