话不多说,先上效果图:
好了,来看xml代码:(为了保持简明,我删除了部分代码)
title层级是这样的:
HorizontalScrollView, RelativeLayout, LinearLayout, TextView
控制横向滚动 包裹标题与光标 包裹标题 六个标题
<?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:background="#eeeeee"
android:orientation="vertical">
<HorizontalScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="50dp">
<LinearLayout
android:id="@+id/llt_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="horizontal">
<TextView
android:id="@+id/tx_applying"
android:layout_width="85dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/applying"
android:textColor="#ff9600"
android:textSize="14sp" />
<TextView
android:id="@+id/tx_holding"
android:layout_width="85dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/holding"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:id="@+id/tx_can_be_redeemed"
android:layout_width="85dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/can_be_redeemed"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:id="@+id/tx_can_be_transfer"
android:layout_width="85dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/can_be_transfer"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:id="@+id/tx_has_finished"
android:layout_width="85dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/has_finished"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:id="@+id/tx_apply_fail"
android:layout_width="85dp"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/apply_fail"
android:textColor="#666666"
android:textSize="14sp" />
</LinearLayout>
<View
android:id="@+id/cursor"
android:layout_width="63dp"
android:layout_height="3dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="11dp"
android:background="#ff9600" />
</RelativeLayout>
</HorizontalScrollView>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#eeeeee" />
<android.support.v4.view.ViewPager
android:id="@+id/fragment_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
然后是Java代码(这里也删除并修改了部分代码)
public class XXXActivity extends BaseActivity implements View.OnClickListener, ViewPager.OnPageChangeListener {
private HorizontalScrollView scroll_view;
private LinearLayout llt_title;
private TextView tx_applying,
tx_holding,
tx_can_be_redeemed,
tx_can_be_transfer,
tx_has_finished,
tx_apply_fail;
private View cursor;
private ViewPager fragment_view_pager;
private MyFragmentPagerAdapter adapter;
private int currentIndex;//当前页卡编号
private int subTitleWidth;//子标题宽度,cursor平移距离
private int titleBarHideOffset;//整个标题未显示的长度
private int firstHideSubTitle;//第一个未显示全的标题(从0数起)
private int hideTitleNum;//未显示标题的数目(从1数起)
@Override
protected void onCreate() {
scroll_view = (HorizontalScrollView) findViewById(R.id.scroll_view);
llt_title = (LinearLayout) findViewById(R.id.llt_title);
tx_applying = (TextView) findViewById(R.id.tx_applying);
tx_holding = (TextView) findViewById(R.id.tx_holding);
tx_can_be_redeemed = (TextView) findViewById(R.id.tx_can_be_redeemed);
tx_can_be_transfer = (TextView) findViewById(R.id.tx_can_be_transfer);
tx_has_finished = (TextView) findViewById(R.id.tx_has_finished);
tx_apply_fail = (TextView) findViewById(R.id.tx_apply_fail);
cursor = findViewById(R.id.cursor);
fragment_view_pager = (ViewPager) findViewById(R.id.fragment_view_pager);
tx_applying.setOnClickListener(this);
tx_holding.setOnClickListener(this);
tx_can_be_redeemed.setOnClickListener(this);
tx_can_be_transfer.setOnClickListener(this);
tx_has_finished.setOnClickListener(this);
tx_apply_fail.setOnClickListener(this);
//获取屏幕宽度、标题宽度
WindowManager manager = this.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
int windowWidth = outMetrics.widthPixels;
subTitleWidth = DisplayUtils.dip2px(this, 85);//一个title的宽度
int titleBarWidth = subTitleWidth * 6;//整个title的宽度
//标题栏最大移动距离与第一个需要移动的title
titleBarHideOffset = titleBarWidth - windowWidth;//未显示出的部分
if (titleBarHideOffset < 0) {
titleBarHideOffset = 0;
hideTitleNum = 0;
} else {//这里逻辑开始略复杂,关键是获取第一个未显示全的title位置
for (int i = 0; i < 6; i++) {
if (windowWidth < subTitleWidth * (i + 1)) {
firstHideSubTitle = i;
break;
}
}
hideTitleNum = 6 - firstHideSubTitle;
}
//view pager
adapter = new MyFragmentPagerAdapter(
getSupportFragmentManager(),
getFragmentList()
);
fragment_view_pager.setAdapter(adapter);
fragment_view_pager.addOnPageChangeListener(this);
}
/**
* 生成碎片列表
*/
private ArrayList<FragProductList> getFragmentList() {
ArrayList<FragProductList> fragmentList = new ArrayList<>();
//此处省略......
return fragmentList;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tx_applying:
fragment_view_pager.setCurrentItem(0);
break;
case R.id.tx_holding:
fragment_view_pager.setCurrentItem(1);
break;
case R.id.tx_can_be_redeemed:
fragment_view_pager.setCurrentItem(2);
break;
case R.id.tx_can_be_transfer:
fragment_view_pager.setCurrentItem(3);
break;
case R.id.tx_has_finished:
fragment_view_pager.setCurrentItem(4);
break;
case R.id.tx_apply_fail:
fragment_view_pager.setCurrentItem(5);
break;
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onPageSelected(int position) {
Animation animation = new TranslateAnimation(
currentIndex * subTitleWidth, //from X
position * subTitleWidth, //to X
0, 0
);
//cursor滑动
currentIndex = position;
animation.setFillAfter(true);//动画终止时停留在最后一帧,不然会回到没有执行前的状态
animation.setInterpolator(new DecelerateInterpolator());//减速动画
animation.setDuration(300);//动画持续时间0.3秒
cursor.startAnimation(animation);
llt_title.getChildAt(position).requestFocus();
//整体滑动
if (hideTitleNum > 0) {
if (position < hideTitleNum) {//左侧
if (scroll_view.getScrollX() > position * subTitleWidth) {
smoothScrollTo(position * subTitleWidth);
}
}
int num = position - firstHideSubTitle;
if (num >= 0) {//右侧
int scrollTo = titleBarHideOffset - (hideTitleNum - (num + 1)) * subTitleWidth;
if (scroll_view.getScrollX() < scrollTo) {
smoothScrollTo(scrollTo);
}
}
}
//title的text变色
changeColor(position);
}
private void changeColor(int position){
int[] color = new int[6];
for(int i=0; i<color.length; i++){
if(i == position){
color[i] = 0xffff9600;
}else{
color[i] = 0xff666666;
}
}
tx_applying.setTextColor(color[0]);
tx_holding.setTextColor(color[1]);
tx_can_be_redeemed.setTextColor(color[2]);
tx_can_be_transfer.setTextColor(color[3]);
tx_has_finished.setTextColor(color[4]);
tx_apply_fail.setTextColor(color[5]);
}
/**
* 流畅滑动
*/
private void smoothScrollTo(final int scrollTo) {
final int currentPosition = scroll_view.getScrollX();
Animation anim = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int scrollOffset = scrollTo - currentPosition;
scroll_view.scrollTo(currentPosition + (int) (scrollOffset * interpolatedTime), 0);
}
};
anim.setDuration(300);
scroll_view.startAnimation(anim);
}
/**
* viewpager adapter
*/
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private ArrayList<FragProductList> list;
public MyFragmentPagerAdapter(FragmentManager fm, ArrayList<FragProductList> list) {
super(fm);
this.list = list;
}
@Override
public FragProductList getItem(int arg0) {
return list.get(arg0);
}
@Override
public int getCount() {
return list.size();
}
}
}
如果有什么不大明白我们可以讨论,反正能直接用就是了