1、起初网上搜了个控件PagerSlidingTabStrip 发现已经很久不更新了,点击tab时候没有动画,不能自己单独使用,自己重写了他的功能即可以配合ViewPager亦可以单独使用
2、内部逻辑重新更改
PagerSlidingTabStrip.java
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Copyright (C), 2019, flyzhang
* Author: flyzhang
* Date: 2019/9/19 16:30
* Description:
*
*
* History:
*
public class PagerSlidingTabStrip extends LinearLayout {
private LinearLayout mTabsContainer;
private ViewPager mViewPager = null;
private Context mContext;
private float mLastPosition = 0;//上次点击
private onTabClickListener mOnTabClickListener;//tab 点击回调
private boolean mSmoothScroll = false;//点击tab viewpager滚动
private Paint mIndicatorPaint, mUnderLinePaint;//下划线 最下面线
private int mIndicatorHeight = 2;//dp 底部滚动线高度
private int mUnderLineWidth = 21;//dp 底部滚动线宽度
private float mCurrentPosition = 0;//当前下标
private float mImageOffset = 2.5f;//dp 减去小红点位置
private boolean mAutoHideBadge = true;//默认自动滚到位置隐藏
private int mSelectTabTextColor = 0xFF07AF39;//tab 选中字体颜色
private int mUnSelectTabTextColor = 0xFF080808;//tab 未选中字体颜色
private int mIndicatorColor = 0xFF1FB84D;//下划线color
private int mUnderIndicatorRound = 2;
private int mUnderLineHeight = 2;//下划线高度
private int mUnderLineColor = 0xFFEFEFEF;//下划线颜色
private int mUnderShadowColor = 0xFFEFEFEF;
private int mUnderRadius = 5;//dp
private int mUnderDx = 0;//dp
private int mUnderDy = 2;//dp
private int mTabTextSize = 14;//tab 字体大小
private int SCREEN_HEIGHT = 0, SCREEN_WIDTH = 0;//屏幕宽高
private int mTabWidth = 0;//每个tab宽
private int mLayoutWeight = 0; //tab 样式 当weight == 1是默认评分屏幕
public PagerSlidingTabStrip(Context context) {
super(context);
initView(context);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
private void initView(Context context) {
setWillNotDraw(false);
mContext = context;
DisplayMetrics dm = getResources().getDisplayMetrics();
mUnderLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mUnderLineWidth, dm);
mImageOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mImageOffset, dm);
mIndicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mIndicatorHeight, dm);
mUnderRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mUnderRadius, dm);
mUnderDx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mUnderDx, dm);
mUnderDy = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mUnderDy, dm);
mUnderIndicatorRound = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mUnderIndicatorRound, dm);
mUnderLineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mUnderLineHeight, dm);
setOrientation(VERTICAL);
mTabsContainer = new LinearLayout(mContext);
mTabsContainer.setOrientation(LinearLayout.HORIZONTAL);
mTabsContainer.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
addView(mTabsContainer);
mIndicatorPaint = new Paint();
mIndicatorPaint.setColor(mIndicatorColor);
mIndicatorPaint.setAntiAlias(true);
mIndicatorPaint.setStyle(Paint.Style.FILL);
mUnderLinePaint = new Paint();
// 设定颜色
mUnderLinePaint.setColor(mUnderLineColor);
// 设定阴影(柔边, X 轴位移, Y 轴位移, 阴影颜色)
mUnderLinePaint.setShadowLayer(mUnderRadius, mUnderDx, mUnderDy, mUnderShadowColor);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (SCREEN_HEIGHT == 0 || SCREEN_WIDTH == 0) {
SCREEN_HEIGHT = getHeight();
SCREEN_WIDTH = getWidth();
}
if(mTabWidth <=0){
mTabWidth = mTabsContainer.getChildAt(0).getWidth();
}
int center = mTabWidth / 2;//每一个item 中间位置
float start = center - mImageOffset;
int temp = mUnderLineWidth / 2;
//画底线的线
canvas.drawRoundRect(mTabWidth * mCurrentPosition + start - temp, SCREEN_HEIGHT - mIndicatorHeight - mUnderLineHeight, mTabWidth * mCurrentPosition + center + temp, SCREEN_HEIGHT - mUnderLineHeight, mUnderIndicatorRound, mUnderIndicatorRound, mIndicatorPaint);
//画最底下线 带阴影
canvas.drawLine(0, SCREEN_HEIGHT - mUnderLineHeight, SCREEN_WIDTH, SCREEN_HEIGHT, mUnderLinePaint);
}
/**
* 设置viewpager
*
* @param viewPager v
*/
public void setViewPager(ViewPager viewPager) {
mViewPager = viewPager;
if (null == mViewPager.getAdapter()) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
int tabCount = mViewPager.getAdapter().getCount();
mTabsContainer.removeAllViews();
for (int i = 0; i < tabCount; i++) {
CharSequence title = mViewPager.getAdapter().getPageTitle(i);
if (title == null) {
throw new IllegalStateException("ViewPager does not Override getPageTitle().");
}
addTextTab(i, title.toString());
}
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//监听组件的滑动。position为当前页面的索引,positionOffset为当前页面偏移的百分比,positionOffsetPixels为当前页面偏移的像素位置
//Log.e("onPageScrolled", "position:" + position);
// Log.e("onPageScrolled", "positionOffset:" + positionOffset);
//Log.e("onPageScrolled", "positionOffsetPixels:" + positionOffsetPixels);
move(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
//监听组件的页面变化。position为当前页面的索引
//Log.e("onPageSelected", "position:" + position);
onTabClickListener(position);
}
@Override
public void onPageScrollStateChanged(int state) {
/**
监听组件的滑动状态变化。state有3种取值:
ViewPager.SCROLL_STATE_IDLE = 0; 空闲状态,也是初始状态,此时组件是静止的。
ViewPager.SCROLL_STATE_DRAGGING = 1; 滑动状态,当手指在屏幕上滑动组件时的状态。
ViewPager.SCROLL_STATE_SETTLING = 2; 滑动后自然沉降的状态,当手指离开屏幕后,组件继续滑动时的状态。
*/
//Log.e("scrollStateChanged", "state:" + state);
}
});
}
/**
* 设置tabs 不适用viewpager
*
* @param titles 标题
*/
public void setTabs(String[] titles) {
setTabs(titles, null);
}
/**
* 设置tabs 不适用viewpager
*
* @param titles 标题
* @param onTabClickListener 点击回调
*/
public void setTabs(String[] titles, onTabClickListener onTabClickListener) {
mTabsContainer.removeAllViews();
if (null == titles || titles.length == 0) {
throw new IllegalStateException("titles is null.");
}
if (null != onTabClickListener) {
mOnTabClickListener = onTabClickListener;
}
for (int i = 0; i < titles.length; i++) {
addTextTab(i, titles[i]);
}
}
/**
* 添加小红点
*
* @param p 位置
*/
public void addBadge(int p) {
if(mAutoHideBadge && p == 0){
setBadge(p, false);
}else{
setBadge(p, true);
}
}
/**
* 隐藏小红点
*
* @param p 位置
*/
public void hideBadge(int p) {
setBadge(p, false);
}
/**
* 隐藏所有小红点
*/
public void hideAllBadge() {
int count = mTabsContainer.getChildCount();
for (int i = 0; i < count; i++) {
setBadge(i, false);
}
}
/**
* 红点 显示隐藏
*
* @param p 红点位置
* @param badge 是否显示
*/
private void setBadge(int p, boolean badge) {
View v = mTabsContainer.getChildAt(p);
if (v != null) {
if (badge) {
v.findViewById(R.id.iv_msg).setVisibility(VISIBLE);
} else {
v.findViewById(R.id.iv_msg).setVisibility(INVISIBLE);
}
}
}
/**
* 移动 跟随设置实时的位置
*
* @param position 当前选择位置(为当前页面的索引)
* @param positionOffset 当前位置到下个位置的百分比(为当前页面偏移的百分比)
* @param positionOffsetPixels 暂时没用(为当前页面偏移的像素位置)
*/
private void move(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPosition = position + positionOffset;
invalidate();
}
/**
* 点击按钮滑动
*
* @param nowPosition 下个位置
* @param smoothScroll 是否 动画
*/
private void move(final int nowPosition, boolean smoothScroll) {
if (!smoothScroll) {
final ValueAnimator anim = ValueAnimator.ofFloat(mCurrentPosition, nowPosition);
anim.setDuration(200);
//anim.setInterpolator(new AccelerateInterpolator());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurrentPosition = (float) animation.getAnimatedValue();
invalidate();
}
});
anim.start();
}
if (null != mViewPager) {
mViewPager.setCurrentItem(nowPosition, smoothScroll);
}
}
/**
* 添加tab
*
* @param p position
* @param title 标题
*/
private void addTextTab(final int p, String title) {
View layoutView = View.inflate(getContext(), R.layout.foundation_sliding_tab_layout, null);
layoutView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
move(p, mSmoothScroll);
if (null == mViewPager) {
onTabClickListener(p);
}
}
});
if(mLayoutWeight == 1){
layoutView.setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f));//设置是否item平分
}else{
layoutView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));//设置是否item平分
}
TextView tab = layoutView.findViewById(R.id.tv_content);
tab.setGravity(Gravity.CENTER);
//默认第一个位置选中
if (p == 0) {
tab.setTextColor(mSelectTabTextColor);
} else {
tab.setTextColor(mUnSelectTabTextColor);
}
tab.setText(title);
tab.setTextSize(mTabTextSize);
tab.setSingleLine();
mTabsContainer.addView(layoutView);
}
/**
* 点击回调
*
* @param p 位置
*/
private void onTabClickListener(int p) {
changeTabTextStatus(p, (int) mLastPosition, mAutoHideBadge);
if (null != mOnTabClickListener && mLastPosition != p) {
mOnTabClickListener.onTabClick(p);
}
mLastPosition = p;
}
/**
* 切换text状态颜色
*
* @param current 当前选择tab
* @param last 上次选择tab
* @param autoHideBadge 自动隐藏红点
*/
private void changeTabTextStatus(int current, int last, boolean autoHideBadge) {
View currentLayoutTab = mTabsContainer.getChildAt(current);
View lastLayoutTab = mTabsContainer.getChildAt(last);
TextView currentTab = currentLayoutTab.findViewById(R.id.tv_content);
if (autoHideBadge) {
View v = currentLayoutTab.findViewById(R.id.iv_msg);
if (null != v) {
v.findViewById(R.id.iv_msg).setVisibility(INVISIBLE);
}
}
TextView lastTab = lastLayoutTab.findViewById(R.id.tv_content);
currentTab.setTextColor(mSelectTabTextColor);
lastTab.setTextColor(mUnSelectTabTextColor);
}
public onTabClickListener getOnTabClickListener() {
return mOnTabClickListener;
}
public void setOnTabClickListener(onTabClickListener mOnTabClickListener) {
this.mOnTabClickListener = mOnTabClickListener;
}
public boolean isSmoothScroll() {
return mSmoothScroll;
}
public void setSmoothScroll(boolean mSmoothScroll) {
this.mSmoothScroll = mSmoothScroll;
}
public boolean isAutoHideBadge() {
return mAutoHideBadge;
}
public void setAutoHideBadge(boolean mAutoHideBadge) {
this.mAutoHideBadge = mAutoHideBadge;
}
public int getLayoutWeight() {
return mLayoutWeight;
}
public void setLayoutWeight(int mLayoutWeight) {
this.mLayoutWeight = mLayoutWeight;
}
/**
* tab点击回调
*/
public interface onTabClickListener {
void onTabClick(int position);
}
}
foundation_sliding_tab_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="62.5dp"
android:gravity="center">
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/foundation_app_name" />
<ImageView
android:id="@+id/iv_msg"
android:layout_width="5dp"
android:layout_height="5dp"
android:layout_alignTop="@+id/tv_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/tv_content"
android:visibility="invisible"
android:src="@drawable/foundation_sliding_tab_dot" />
RelativeLayout>
RelativeLayout>
tabs.setLayoutWeight(0);//设置是否平分充满屏幕 1充满屏幕
tabs.setSmoothScroll(true);//点击tab是否ViewPager进行动画滚动
//tabs.setViewPager(pager);//设置pager 或者设置titles
tabs.setTabs(new String[]{"已完成","已收货","待评价"});//不能和setViewPager同时使用
tabs.setOnTabClickListener(null);//设置点击tab或者活动ViewPager回调
tabs.setAutoHideBadge(true);//设置滚动tab位置自动隐藏小红点
tabs.addBadge(0);//添加小红点位置
tabs.hideAllBadge();
tabs.hideBadge(0);