前言
我们知道,现在实现Tab切换之类的效果都是android TabLayout+ViewPager配合使用。刚开始开发那段时期,第一次看见某app滑动tap标题变色下划线移动效果,当时非常喜欢,于是从网上找资料,发现它是一个用自定义view绘制画图实现的。本人不是对这种实现有偏见,只是觉得它太繁琐复杂,但是我的个性是有些功能搞懂Viewpager的原理后,自己动手就能实现了。
好了,废话不说了,上源码和效果图:Tap切换字体变色下划线移动
实现逻辑
首先,效果看起来还是蛮棒的,代码怎么写呢?源码已经发了, 下面粘贴出来,关键点都在代码中讲解了。首先,从整体控件布局上看,它包含三个部分,分别是一个FragmentActivity(v4.app.fragment 需要宿主继承)、2个fragment、一个viewpager。
其次,是下划线的测量和计算。
最后,主要看viewpager的页面切换监听。
实现代码
public class MainActivity extends FragmentActivity implements View.OnClickListener, ViewPager.OnPageChangeListener{
private TextView mTextViews1;
private TextView mTextViews2;
private ViewPager mViewpager;
/*
* tab下划线
*/
private LinearLayout.LayoutParams params;
private int width;
private LinearLayout tabView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUi();
}
//初始化
private void initUi() {
mTextViews1= (TextView) findViewById(R.id.news_tab);
mTextViews2=(TextView) findViewById(R.id.daily_tab);
tabView= (LinearLayout)findViewById(R.id.tab_view);
mViewpager =(ViewPager) findViewById(R.id.viewpager);
mViewpager.addOnPageChangeListener(this);
mTextViews1.setOnClickListener(this);
mTextViews2.setOnClickListener(this);
initTabLine();
List<Fragment> mList=new ArrayList<Fragment>();
mList.add(new OneFragment());
mList.add(new OneFragment());
mViewpager.setAdapter(new MissonPagerAdapter(getSupportFragmentManager(),mList));
mViewpager.setOffscreenPageLimit(0);//设置页面缓存数量 默认为2表示当前页左右的缓存个数 加当前页其实3个页面
}
/**
* 初始化tab下划线
* 实现步骤:
* 1、获取屏幕大小 比例设置宽度
* 2、然后有几个tab就分几份 移动时改变外边距参数
*/
private void initTabLine() {
params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.widthPixels / 2;
params.width = width;
tabView.setLayoutParams(params);
}
/**
* 滑动监听
* @param position 第一个页面索引为0
* @param positionOffset 从左向右 0-0.99 反之 0.99-0 (主要跟右边页面有关系) 当0.5以上下一页 反之回到滑动前
* @param positionOffsetPixels 整数值
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(positionOffset!=0){
mTextViews2.setTextColor(Color.argb(255, (int) (255*positionOffset), (int) (115*positionOffset),0));
mTextViews1.setTextColor(Color.argb(255, (int) (255*(1-positionOffset)), (int) (115*(1-positionOffset)),0));
params.leftMargin = (int)(width*positionOffset);
tabView.setLayoutParams(params);
}
}
//滑动结束
@Override
public void onPageSelected(int position) {
if (position==0){
mTextViews1.setTextColor(Color.argb( 255, 255, 115, 0));
mTextViews2.setTextColor(Color.argb( 255, 0, 0, 0));
params.leftMargin=0;
tabView.setLayoutParams(params);
}else if (position==1){
params.leftMargin = width;
tabView.setLayoutParams(params);
mTextViews1.setTextColor(Color.argb(255,0,0,0));
mTextViews2.setTextColor(Color.argb( 255, 255, 155, 0));
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
/**
* 点击切换
*/
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.news_tab:
mViewpager.setCurrentItem(0,true);
params.leftMargin=width/2;
tabView.setLayoutParams(params);
break;
case R.id.daily_tab:
mViewpager.setCurrentItem(1,true);
params.leftMargin = width*2+width/2;
tabView.setLayoutParams(params);
break;
}
}
布局文件就补贴出来了,很简单。欢迎大家下载demo。
源码下载:Tap切换字体变色下划线移动