package com.fuban.user.views;
|
|
import android.animation.TypeEvaluator;
|
import android.animation.ValueAnimator;
|
import android.content.Context;
|
import android.content.res.TypedArray;
|
import android.graphics.Canvas;
|
import android.graphics.Color;
|
import android.graphics.Paint;
|
import android.graphics.Path;
|
import android.graphics.Rect;
|
import android.graphics.drawable.GradientDrawable;
|
import android.os.Bundle;
|
import android.os.Parcelable;
|
import android.util.AttributeSet;
|
import android.util.SparseArray;
|
import android.util.TypedValue;
|
import android.view.Gravity;
|
import android.view.View;
|
import android.view.ViewGroup;
|
import android.view.animation.OvershootInterpolator;
|
import android.widget.FrameLayout;
|
import android.widget.ImageView;
|
import android.widget.LinearLayout;
|
import android.widget.TextView;
|
|
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.FragmentActivity;
|
|
import com.flyco.tablayout.listener.CustomTabEntity;
|
import com.flyco.tablayout.listener.OnTabSelectListener;
|
import com.flyco.tablayout.utils.FragmentChangeManager;
|
import com.flyco.tablayout.utils.UnreadMsgUtils;
|
import com.flyco.tablayout.widget.MsgView;
|
import com.fuban.user.R;
|
|
import java.util.ArrayList;
|
|
/** 没有继承HorizontalScrollView不能滑动,对于ViewPager无依赖 */
|
public class CommonTabLayout extends FrameLayout implements ValueAnimator.AnimatorUpdateListener {
|
private Context mContext;
|
private ArrayList<CustomTabEntity> mTabEntitys = new ArrayList<>();
|
private LinearLayout mTabsContainer;
|
private int mCurrentTab;
|
private int mLastTab;
|
private int mTabCount;
|
/** 用于绘制显示器 */
|
private Rect mIndicatorRect = new Rect();
|
private GradientDrawable mIndicatorDrawable = new GradientDrawable();
|
|
private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private Path mTrianglePath = new Path();
|
private static final int STYLE_NORMAL = 0;
|
private static final int STYLE_TRIANGLE = 1;
|
private static final int STYLE_BLOCK = 2;
|
private int mIndicatorStyle = STYLE_NORMAL;
|
|
private float mTabPadding;
|
private boolean mTabSpaceEqual;
|
private float mTabWidth;
|
|
/** indicator */
|
private int mIndicatorColor;
|
private float mIndicatorHeight;
|
private float mIndicatorWidth;
|
private float mIndicatorCornerRadius;
|
private float mIndicatorMarginLeft;
|
private float mIndicatorMarginTop;
|
private float mIndicatorMarginRight;
|
private float mIndicatorMarginBottom;
|
private long mIndicatorAnimDuration;
|
private boolean mIndicatorAnimEnable;
|
private boolean mIndicatorBounceEnable;
|
private int mIndicatorGravity;
|
|
/** underline */
|
private int mUnderlineColor;
|
private float mUnderlineHeight;
|
private int mUnderlineGravity;
|
|
/** divider */
|
private int mDividerColor;
|
private float mDividerWidth;
|
private float mDividerPadding;
|
|
/** title */
|
private static final int TEXT_BOLD_NONE = 0;
|
private static final int TEXT_BOLD_WHEN_SELECT = 1;
|
private static final int TEXT_BOLD_BOTH = 2;
|
private float mTextsize;
|
private float mSelectTextsize;
|
private int mTextSelectColor;
|
private int mTextUnselectColor;
|
private int mTextBold;
|
private boolean mTextAllCaps;
|
|
/** icon */
|
private boolean mIconVisible;
|
private int mIconGravity;
|
private float mIconWidth;
|
private float mIconHeight;
|
private float mIconMargin;
|
|
private int mHeight;
|
|
/** anim */
|
private ValueAnimator mValueAnimator;
|
private OvershootInterpolator mInterpolator = new OvershootInterpolator(1.5f);
|
|
private FragmentChangeManager mFragmentChangeManager;
|
|
public CommonTabLayout(Context context) {
|
this(context, null, 0);
|
}
|
|
public CommonTabLayout(Context context, AttributeSet attrs) {
|
this(context, attrs, 0);
|
}
|
|
public CommonTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
super(context, attrs, defStyleAttr);
|
setWillNotDraw(false);//重写onDraw方法,需要调用这个方法来清除flag
|
setClipChildren(false);
|
setClipToPadding(false);
|
|
this.mContext = context;
|
mTabsContainer = new LinearLayout(context);
|
addView(mTabsContainer);
|
|
obtainAttributes(context, attrs);
|
|
//get layout_height
|
String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");
|
|
//create ViewPager
|
if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
|
} else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
|
} else {
|
int[] systemAttrs = {android.R.attr.layout_height};
|
TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
|
mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
|
a.recycle();
|
}
|
|
mValueAnimator = ValueAnimator.ofObject(new PointEvaluator(), mLastP, mCurrentP);
|
mValueAnimator.addUpdateListener(this);
|
}
|
|
private void obtainAttributes(Context context, AttributeSet attrs) {
|
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CommonTabLayout);
|
|
mIndicatorStyle = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_style, 0);
|
mIndicatorColor = ta.getColor(R.styleable.CommonTabLayout_tl_indicator_color, Color.parseColor(mIndicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff"));
|
mIndicatorHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_height,
|
dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));
|
mIndicatorWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_width, dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));
|
mIndicatorCornerRadius = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_corner_radius, dp2px(mIndicatorStyle == STYLE_BLOCK ? -1 : 0));
|
mIndicatorMarginLeft = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_left, dp2px(0));
|
mIndicatorMarginTop = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_top, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
|
mIndicatorMarginRight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_right, dp2px(0));
|
mIndicatorMarginBottom = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_bottom, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
|
mIndicatorAnimEnable = ta.getBoolean(R.styleable.CommonTabLayout_tl_indicator_anim_enable, true);
|
mIndicatorBounceEnable = ta.getBoolean(R.styleable.CommonTabLayout_tl_indicator_bounce_enable, true);
|
mIndicatorAnimDuration = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_anim_duration, -1);
|
mIndicatorGravity = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_gravity, Gravity.BOTTOM);
|
|
mUnderlineColor = ta.getColor(R.styleable.CommonTabLayout_tl_underline_color, Color.parseColor("#ffffff"));
|
mUnderlineHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_underline_height, dp2px(0));
|
mUnderlineGravity = ta.getInt(R.styleable.CommonTabLayout_tl_underline_gravity, Gravity.BOTTOM);
|
|
mDividerColor = ta.getColor(R.styleable.CommonTabLayout_tl_divider_color, Color.parseColor("#ffffff"));
|
mDividerWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_divider_width, dp2px(0));
|
mDividerPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_divider_padding, dp2px(12));
|
|
mTextsize = ta.getDimension(R.styleable.CommonTabLayout_tl_textsize, sp2px(13f));
|
mSelectTextsize = sp2px(16f);
|
mTextSelectColor = ta.getColor(R.styleable.CommonTabLayout_tl_textSelectColor, Color.parseColor("#ffffff"));
|
mTextUnselectColor = ta.getColor(R.styleable.CommonTabLayout_tl_textUnselectColor, Color.parseColor("#AAffffff"));
|
mTextBold = ta.getInt(R.styleable.CommonTabLayout_tl_textBold, TEXT_BOLD_NONE);
|
mTextAllCaps = ta.getBoolean(R.styleable.CommonTabLayout_tl_textAllCaps, false);
|
|
mIconVisible = ta.getBoolean(R.styleable.CommonTabLayout_tl_iconVisible, true);
|
mIconGravity = ta.getInt(R.styleable.CommonTabLayout_tl_iconGravity, Gravity.TOP);
|
mIconWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_iconWidth, dp2px(0));
|
mIconHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_iconHeight, dp2px(0));
|
mIconMargin = ta.getDimension(R.styleable.CommonTabLayout_tl_iconMargin, dp2px(2.5f));
|
|
mTabSpaceEqual = ta.getBoolean(R.styleable.CommonTabLayout_tl_tab_space_equal, true);
|
mTabWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_width, dp2px(-1));
|
mTabPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? dp2px(0) : dp2px(10));
|
|
ta.recycle();
|
}
|
|
public void setTabData(ArrayList<CustomTabEntity> tabEntitys) {
|
if (tabEntitys == null || tabEntitys.size() == 0) {
|
throw new IllegalStateException("TabEntitys can not be NULL or EMPTY !");
|
}
|
|
this.mTabEntitys.clear();
|
this.mTabEntitys.addAll(tabEntitys);
|
|
notifyDataSetChanged();
|
}
|
|
/** 关联数据支持同时切换fragments */
|
public void setTabData(ArrayList<CustomTabEntity> tabEntitys, FragmentActivity fa, int containerViewId, ArrayList<Fragment> fragments) {
|
mFragmentChangeManager = new FragmentChangeManager(fa.getSupportFragmentManager(), containerViewId, fragments);
|
setTabData(tabEntitys);
|
}
|
|
/** 更新数据 */
|
public void notifyDataSetChanged() {
|
mTabsContainer.removeAllViews();
|
this.mTabCount = mTabEntitys.size();
|
View tabView;
|
for (int i = 0; i < mTabCount; i++) {
|
if (mIconGravity == Gravity.LEFT) {
|
tabView = View.inflate(mContext, R.layout.layout_tab_left, null);
|
} else if (mIconGravity == Gravity.RIGHT) {
|
tabView = View.inflate(mContext, R.layout.layout_tab_right, null);
|
} else if (mIconGravity == Gravity.BOTTOM) {
|
tabView = View.inflate(mContext, R.layout.layout_tab_bottom, null);
|
} else {
|
tabView = View.inflate(mContext, R.layout.layout_tab_top, null);
|
}
|
|
tabView.setTag(i);
|
addTab(i, tabView);
|
}
|
|
updateTabStyles();
|
}
|
|
/** 创建并添加tab */
|
private void addTab(final int position, View tabView) {
|
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
|
tv_tab_title.setText(mTabEntitys.get(position).getTabTitle());
|
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
|
iv_tab_icon.setImageResource(mTabEntitys.get(position).getTabUnselectedIcon());
|
|
tabView.setOnClickListener(new OnClickListener() {
|
@Override
|
public void onClick(View v) {
|
int position = (Integer) v.getTag();
|
if (mCurrentTab != position) {
|
setCurrentTab(position);
|
if (mListener != null) {
|
mListener.onTabSelect(position);
|
}
|
} else {
|
if (mListener != null) {
|
mListener.onTabReselect(position);
|
}
|
}
|
}
|
});
|
|
/** 每一个Tab的布局参数 */
|
LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?
|
new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
|
new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
if (mTabWidth > 0) {
|
lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);
|
}
|
mTabsContainer.addView(tabView, position, lp_tab);
|
}
|
|
private void updateTabStyles() {
|
for (int i = 0; i < mTabCount; i++) {
|
View tabView = mTabsContainer.getChildAt(i);
|
tabView.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
|
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
|
tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);
|
tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX,i == mCurrentTab ? mSelectTextsize:mTextsize);
|
// tv_tab_title.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
|
if (mTextAllCaps) {
|
tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());
|
}
|
|
if (mTextBold == TEXT_BOLD_BOTH) {
|
tv_tab_title.getPaint().setFakeBoldText(true);
|
} else if (mTextBold == TEXT_BOLD_NONE) {
|
tv_tab_title.getPaint().setFakeBoldText(false);
|
}
|
|
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
|
if (mIconVisible) {
|
iv_tab_icon.setVisibility(View.VISIBLE);
|
CustomTabEntity tabEntity = mTabEntitys.get(i);
|
iv_tab_icon.setImageResource(i == mCurrentTab ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());
|
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
|
mIconWidth <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconWidth,
|
mIconHeight <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconHeight);
|
if (mIconGravity == Gravity.LEFT) {
|
lp.rightMargin = (int) mIconMargin;
|
} else if (mIconGravity == Gravity.RIGHT) {
|
lp.leftMargin = (int) mIconMargin;
|
} else if (mIconGravity == Gravity.BOTTOM) {
|
lp.topMargin = (int) mIconMargin;
|
} else {
|
lp.bottomMargin = (int) mIconMargin;
|
}
|
|
iv_tab_icon.setLayoutParams(lp);
|
} else {
|
iv_tab_icon.setVisibility(View.GONE);
|
}
|
}
|
}
|
|
private void updateTabSelection(int position) {
|
for (int i = 0; i < mTabCount; ++i) {
|
View tabView = mTabsContainer.getChildAt(i);
|
final boolean isSelect = i == position;
|
TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
|
tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);
|
tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX,isSelect ? mSelectTextsize : mTextsize);
|
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
|
CustomTabEntity tabEntity = mTabEntitys.get(i);
|
iv_tab_icon.setImageResource(isSelect ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());
|
if (mTextBold == TEXT_BOLD_WHEN_SELECT) {
|
tab_title.getPaint().setFakeBoldText(isSelect);
|
}
|
}
|
}
|
|
private void calcOffset() {
|
final View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
|
mCurrentP.left = currentTabView.getLeft();
|
mCurrentP.right = currentTabView.getRight();
|
|
final View lastTabView = mTabsContainer.getChildAt(this.mLastTab);
|
mLastP.left = lastTabView.getLeft();
|
mLastP.right = lastTabView.getRight();
|
|
// Log.d("AAA", "mLastP--->" + mLastP.left + "&" + mLastP.right);
|
// Log.d("AAA", "mCurrentP--->" + mCurrentP.left + "&" + mCurrentP.right);
|
if (mLastP.left == mCurrentP.left && mLastP.right == mCurrentP.right) {
|
invalidate();
|
} else {
|
mValueAnimator.setObjectValues(mLastP, mCurrentP);
|
if (mIndicatorBounceEnable) {
|
mValueAnimator.setInterpolator(mInterpolator);
|
}
|
|
if (mIndicatorAnimDuration < 0) {
|
mIndicatorAnimDuration = mIndicatorBounceEnable ? 500 : 250;
|
}
|
mValueAnimator.setDuration(mIndicatorAnimDuration);
|
mValueAnimator.start();
|
}
|
}
|
|
private void calcIndicatorRect() {
|
View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
|
float left = currentTabView.getLeft();
|
float right = currentTabView.getRight();
|
|
mIndicatorRect.left = (int) left;
|
mIndicatorRect.right = (int) right;
|
|
if (mIndicatorWidth < 0) { //indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip
|
|
} else {//indicatorWidth大于0时,圆角矩形以及三角形
|
float indicatorLeft = currentTabView.getLeft() + (currentTabView.getWidth() - mIndicatorWidth) / 2;
|
|
mIndicatorRect.left = (int) indicatorLeft;
|
mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
|
}
|
}
|
|
@Override
|
public void onAnimationUpdate(ValueAnimator animation) {
|
View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
|
IndicatorPoint p = (IndicatorPoint) animation.getAnimatedValue();
|
mIndicatorRect.left = (int) p.left;
|
mIndicatorRect.right = (int) p.right;
|
|
if (mIndicatorWidth < 0) { //indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip
|
|
} else {//indicatorWidth大于0时,圆角矩形以及三角形
|
float indicatorLeft = p.left + (currentTabView.getWidth() - mIndicatorWidth) / 2;
|
|
mIndicatorRect.left = (int) indicatorLeft;
|
mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
|
}
|
invalidate();
|
}
|
|
private boolean mIsFirstDraw = true;
|
|
@Override
|
protected void onDraw(Canvas canvas) {
|
super.onDraw(canvas);
|
|
if (isInEditMode() || mTabCount <= 0) {
|
return;
|
}
|
|
int height = getHeight();
|
int paddingLeft = getPaddingLeft();
|
// draw divider
|
if (mDividerWidth > 0) {
|
mDividerPaint.setStrokeWidth(mDividerWidth);
|
mDividerPaint.setColor(mDividerColor);
|
for (int i = 0; i < mTabCount - 1; i++) {
|
View tab = mTabsContainer.getChildAt(i);
|
canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(), height - mDividerPadding, mDividerPaint);
|
}
|
}
|
|
// draw underline
|
if (mUnderlineHeight > 0) {
|
mRectPaint.setColor(mUnderlineColor);
|
if (mUnderlineGravity == Gravity.BOTTOM) {
|
canvas.drawRect(paddingLeft, height - mUnderlineHeight, mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);
|
} else {
|
canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth() + paddingLeft, mUnderlineHeight, mRectPaint);
|
}
|
}
|
|
//draw indicator line
|
if (mIndicatorAnimEnable) {
|
if (mIsFirstDraw) {
|
mIsFirstDraw = false;
|
calcIndicatorRect();
|
}
|
} else {
|
calcIndicatorRect();
|
}
|
|
|
if (mIndicatorStyle == STYLE_TRIANGLE) {
|
if (mIndicatorHeight > 0) {
|
mTrianglePaint.setColor(mIndicatorColor);
|
mTrianglePath.reset();
|
mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);
|
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2 + mIndicatorRect.right / 2, height - mIndicatorHeight);
|
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);
|
mTrianglePath.close();
|
canvas.drawPath(mTrianglePath, mTrianglePaint);
|
}
|
} else if (mIndicatorStyle == STYLE_BLOCK) {
|
if (mIndicatorHeight < 0) {
|
mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;
|
} else {
|
|
}
|
|
if (mIndicatorHeight > 0) {
|
if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {
|
mIndicatorCornerRadius = mIndicatorHeight / 2;
|
}
|
|
mIndicatorDrawable.setColor(mIndicatorColor);
|
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
|
(int) mIndicatorMarginTop, (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),
|
(int) (mIndicatorMarginTop + mIndicatorHeight));
|
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
|
mIndicatorDrawable.draw(canvas);
|
}
|
} else {
|
/* mRectPaint.setColor(mIndicatorColor);
|
calcIndicatorRect();
|
canvas.drawRect(getPaddingLeft() + mIndicatorRect.left, getHeight() - mIndicatorHeight,
|
mIndicatorRect.right + getPaddingLeft(), getHeight(), mRectPaint);*/
|
|
if (mIndicatorHeight > 0) {
|
mIndicatorDrawable.setColor(mIndicatorColor);
|
if (mIndicatorGravity == Gravity.BOTTOM) {
|
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
|
height - (int) mIndicatorHeight - (int) mIndicatorMarginBottom,
|
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
|
height - (int) mIndicatorMarginBottom);
|
} else {
|
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
|
(int) mIndicatorMarginTop,
|
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
|
(int) mIndicatorHeight + (int) mIndicatorMarginTop);
|
}
|
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
|
mIndicatorDrawable.draw(canvas);
|
}
|
}
|
}
|
|
//setter and getter
|
public void setCurrentTab(int currentTab) {
|
mLastTab = this.mCurrentTab;
|
this.mCurrentTab = currentTab;
|
updateTabSelection(currentTab);
|
if (mFragmentChangeManager != null) {
|
mFragmentChangeManager.setFragments(currentTab);
|
}
|
if (mIndicatorAnimEnable) {
|
calcOffset();
|
} else {
|
invalidate();
|
}
|
}
|
|
public void setIndicatorStyle(int indicatorStyle) {
|
this.mIndicatorStyle = indicatorStyle;
|
invalidate();
|
}
|
|
public void setTabPadding(float tabPadding) {
|
this.mTabPadding = dp2px(tabPadding);
|
updateTabStyles();
|
}
|
|
public void setTabSpaceEqual(boolean tabSpaceEqual) {
|
this.mTabSpaceEqual = tabSpaceEqual;
|
updateTabStyles();
|
}
|
|
public void setTabWidth(float tabWidth) {
|
this.mTabWidth = dp2px(tabWidth);
|
updateTabStyles();
|
}
|
|
public void setIndicatorColor(int indicatorColor) {
|
this.mIndicatorColor = indicatorColor;
|
invalidate();
|
}
|
|
public void setIndicatorHeight(float indicatorHeight) {
|
this.mIndicatorHeight = dp2px(indicatorHeight);
|
invalidate();
|
}
|
|
public void setIndicatorWidth(float indicatorWidth) {
|
this.mIndicatorWidth = dp2px(indicatorWidth);
|
invalidate();
|
}
|
|
public void setIndicatorCornerRadius(float indicatorCornerRadius) {
|
this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);
|
invalidate();
|
}
|
|
public void setIndicatorGravity(int indicatorGravity) {
|
this.mIndicatorGravity = indicatorGravity;
|
invalidate();
|
}
|
|
public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
|
float indicatorMarginRight, float indicatorMarginBottom) {
|
this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);
|
this.mIndicatorMarginTop = dp2px(indicatorMarginTop);
|
this.mIndicatorMarginRight = dp2px(indicatorMarginRight);
|
this.mIndicatorMarginBottom = dp2px(indicatorMarginBottom);
|
invalidate();
|
}
|
|
public void setIndicatorAnimDuration(long indicatorAnimDuration) {
|
this.mIndicatorAnimDuration = indicatorAnimDuration;
|
}
|
|
public void setIndicatorAnimEnable(boolean indicatorAnimEnable) {
|
this.mIndicatorAnimEnable = indicatorAnimEnable;
|
}
|
|
public void setIndicatorBounceEnable(boolean indicatorBounceEnable) {
|
this.mIndicatorBounceEnable = indicatorBounceEnable;
|
}
|
|
public void setUnderlineColor(int underlineColor) {
|
this.mUnderlineColor = underlineColor;
|
invalidate();
|
}
|
|
public void setUnderlineHeight(float underlineHeight) {
|
this.mUnderlineHeight = dp2px(underlineHeight);
|
invalidate();
|
}
|
|
public void setUnderlineGravity(int underlineGravity) {
|
this.mUnderlineGravity = underlineGravity;
|
invalidate();
|
}
|
|
public void setDividerColor(int dividerColor) {
|
this.mDividerColor = dividerColor;
|
invalidate();
|
}
|
|
public void setDividerWidth(float dividerWidth) {
|
this.mDividerWidth = dp2px(dividerWidth);
|
invalidate();
|
}
|
|
public void setDividerPadding(float dividerPadding) {
|
this.mDividerPadding = dp2px(dividerPadding);
|
invalidate();
|
}
|
|
public void setTextsize(float textsize) {
|
this.mTextsize = sp2px(textsize);
|
updateTabStyles();
|
}
|
|
public void setTextSelectColor(int textSelectColor) {
|
this.mTextSelectColor = textSelectColor;
|
updateTabStyles();
|
}
|
|
public void setTextUnselectColor(int textUnselectColor) {
|
this.mTextUnselectColor = textUnselectColor;
|
updateTabStyles();
|
}
|
|
public void setTextBold(int textBold) {
|
this.mTextBold = textBold;
|
updateTabStyles();
|
}
|
|
public void setIconVisible(boolean iconVisible) {
|
this.mIconVisible = iconVisible;
|
updateTabStyles();
|
}
|
|
public void setIconGravity(int iconGravity) {
|
this.mIconGravity = iconGravity;
|
notifyDataSetChanged();
|
}
|
|
public void setIconWidth(float iconWidth) {
|
this.mIconWidth = dp2px(iconWidth);
|
updateTabStyles();
|
}
|
|
public void setIconHeight(float iconHeight) {
|
this.mIconHeight = dp2px(iconHeight);
|
updateTabStyles();
|
}
|
|
public void setIconMargin(float iconMargin) {
|
this.mIconMargin = dp2px(iconMargin);
|
updateTabStyles();
|
}
|
|
public void setTextAllCaps(boolean textAllCaps) {
|
this.mTextAllCaps = textAllCaps;
|
updateTabStyles();
|
}
|
|
|
public int getTabCount() {
|
return mTabCount;
|
}
|
|
public int getCurrentTab() {
|
return mCurrentTab;
|
}
|
|
public int getIndicatorStyle() {
|
return mIndicatorStyle;
|
}
|
|
public float getTabPadding() {
|
return mTabPadding;
|
}
|
|
public boolean isTabSpaceEqual() {
|
return mTabSpaceEqual;
|
}
|
|
public float getTabWidth() {
|
return mTabWidth;
|
}
|
|
public int getIndicatorColor() {
|
return mIndicatorColor;
|
}
|
|
public float getIndicatorHeight() {
|
return mIndicatorHeight;
|
}
|
|
public float getIndicatorWidth() {
|
return mIndicatorWidth;
|
}
|
|
public float getIndicatorCornerRadius() {
|
return mIndicatorCornerRadius;
|
}
|
|
public float getIndicatorMarginLeft() {
|
return mIndicatorMarginLeft;
|
}
|
|
public float getIndicatorMarginTop() {
|
return mIndicatorMarginTop;
|
}
|
|
public float getIndicatorMarginRight() {
|
return mIndicatorMarginRight;
|
}
|
|
public float getIndicatorMarginBottom() {
|
return mIndicatorMarginBottom;
|
}
|
|
public long getIndicatorAnimDuration() {
|
return mIndicatorAnimDuration;
|
}
|
|
public boolean isIndicatorAnimEnable() {
|
return mIndicatorAnimEnable;
|
}
|
|
public boolean isIndicatorBounceEnable() {
|
return mIndicatorBounceEnable;
|
}
|
|
public int getUnderlineColor() {
|
return mUnderlineColor;
|
}
|
|
public float getUnderlineHeight() {
|
return mUnderlineHeight;
|
}
|
|
public int getDividerColor() {
|
return mDividerColor;
|
}
|
|
public float getDividerWidth() {
|
return mDividerWidth;
|
}
|
|
public float getDividerPadding() {
|
return mDividerPadding;
|
}
|
|
public float getTextsize() {
|
return mTextsize;
|
}
|
|
public int getTextSelectColor() {
|
return mTextSelectColor;
|
}
|
|
public int getTextUnselectColor() {
|
return mTextUnselectColor;
|
}
|
|
public int getTextBold() {
|
return mTextBold;
|
}
|
|
public boolean isTextAllCaps() {
|
return mTextAllCaps;
|
}
|
|
public int getIconGravity() {
|
return mIconGravity;
|
}
|
|
public float getIconWidth() {
|
return mIconWidth;
|
}
|
|
public float getIconHeight() {
|
return mIconHeight;
|
}
|
|
public float getIconMargin() {
|
return mIconMargin;
|
}
|
|
public boolean isIconVisible() {
|
return mIconVisible;
|
}
|
|
|
public ImageView getIconView(int tab) {
|
View tabView = mTabsContainer.getChildAt(tab);
|
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
|
return iv_tab_icon;
|
}
|
|
public TextView getTitleView(int tab) {
|
View tabView = mTabsContainer.getChildAt(tab);
|
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
|
return tv_tab_title;
|
}
|
|
//setter and getter
|
|
// show MsgTipView
|
private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private SparseArray<Boolean> mInitSetMap = new SparseArray<>();
|
|
/**
|
* 显示未读消息
|
*
|
* @param position 显示tab位置
|
* @param num num小于等于0显示红点,num大于0显示数字
|
*/
|
public void showMsg(int position, int num) {
|
if (position >= mTabCount) {
|
position = mTabCount - 1;
|
}
|
|
View tabView = mTabsContainer.getChildAt(position);
|
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
|
if (tipView != null) {
|
UnreadMsgUtils.show(tipView, num);
|
|
if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
|
return;
|
}
|
|
if (!mIconVisible) {
|
setMsgMargin(position, 2, 2);
|
} else {
|
setMsgMargin(position, 0,
|
mIconGravity == Gravity.LEFT || mIconGravity == Gravity.RIGHT ? 4 : 0);
|
}
|
|
mInitSetMap.put(position, true);
|
}
|
}
|
|
/**
|
* 显示未读红点
|
*
|
* @param position 显示tab位置
|
*/
|
public void showDot(int position) {
|
if (position >= mTabCount) {
|
position = mTabCount - 1;
|
}
|
showMsg(position, 0);
|
}
|
|
public void hideMsg(int position) {
|
if (position >= mTabCount) {
|
position = mTabCount - 1;
|
}
|
|
View tabView = mTabsContainer.getChildAt(position);
|
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
|
if (tipView != null) {
|
tipView.setVisibility(View.GONE);
|
}
|
}
|
|
/**
|
* 设置提示红点偏移,注意
|
* 1.控件为固定高度:参照点为tab内容的右上角
|
* 2.控件高度不固定(WRAP_CONTENT):参照点为tab内容的右上角,此时高度已是红点的最高显示范围,所以这时bottomPadding其实就是topPadding
|
*/
|
public void setMsgMargin(int position, float leftPadding, float bottomPadding) {
|
if (position >= mTabCount) {
|
position = mTabCount - 1;
|
}
|
View tabView = mTabsContainer.getChildAt(position);
|
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
|
if (tipView != null) {
|
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
|
mTextPaint.setTextSize(mTextsize);
|
float textWidth = mTextPaint.measureText(tv_tab_title.getText().toString());
|
float textHeight = mTextPaint.descent() - mTextPaint.ascent();
|
MarginLayoutParams lp = (MarginLayoutParams) tipView.getLayoutParams();
|
|
float iconH = mIconHeight;
|
float margin = 0;
|
if (mIconVisible) {
|
if (iconH <= 0) {
|
iconH = mContext.getResources().getDrawable(mTabEntitys.get(position).getTabSelectedIcon()).getIntrinsicHeight();
|
}
|
margin = mIconMargin;
|
}
|
|
if (mIconGravity == Gravity.TOP || mIconGravity == Gravity.BOTTOM) {
|
lp.leftMargin = dp2px(leftPadding);
|
lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight - iconH - margin) / 2 - dp2px(bottomPadding) : dp2px(bottomPadding);
|
} else {
|
lp.leftMargin = dp2px(leftPadding);
|
lp.topMargin = mHeight > 0 ? (int) (mHeight - Math.max(textHeight, iconH)) / 2 - dp2px(bottomPadding) : dp2px(bottomPadding);
|
}
|
|
tipView.setLayoutParams(lp);
|
}
|
}
|
|
/** 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取MsgView对象从而各种设置 */
|
public MsgView getMsgView(int position) {
|
if (position >= mTabCount) {
|
position = mTabCount - 1;
|
}
|
View tabView = mTabsContainer.getChildAt(position);
|
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
|
return tipView;
|
}
|
|
private OnTabSelectListener mListener;
|
|
public void setOnTabSelectListener(OnTabSelectListener listener) {
|
this.mListener = listener;
|
}
|
|
|
@Override
|
protected Parcelable onSaveInstanceState() {
|
Bundle bundle = new Bundle();
|
bundle.putParcelable("instanceState", super.onSaveInstanceState());
|
bundle.putInt("mCurrentTab", mCurrentTab);
|
return bundle;
|
}
|
|
@Override
|
protected void onRestoreInstanceState(Parcelable state) {
|
if (state instanceof Bundle) {
|
Bundle bundle = (Bundle) state;
|
mCurrentTab = bundle.getInt("mCurrentTab");
|
state = bundle.getParcelable("instanceState");
|
if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {
|
updateTabSelection(mCurrentTab);
|
}
|
}
|
super.onRestoreInstanceState(state);
|
}
|
|
class IndicatorPoint {
|
public float left;
|
public float right;
|
}
|
|
private IndicatorPoint mCurrentP = new IndicatorPoint();
|
private IndicatorPoint mLastP = new IndicatorPoint();
|
|
class PointEvaluator implements TypeEvaluator<IndicatorPoint> {
|
@Override
|
public IndicatorPoint evaluate(float fraction, IndicatorPoint startValue, IndicatorPoint endValue) {
|
float left = startValue.left + fraction * (endValue.left - startValue.left);
|
float right = startValue.right + fraction * (endValue.right - startValue.right);
|
IndicatorPoint point = new IndicatorPoint();
|
point.left = left;
|
point.right = right;
|
return point;
|
}
|
}
|
|
|
protected int dp2px(float dp) {
|
final float scale = mContext.getResources().getDisplayMetrics().density;
|
return (int) (dp * scale + 0.5f);
|
}
|
|
protected int sp2px(float sp) {
|
final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;
|
return (int) (sp * scale + 0.5f);
|
}
|
|
}
|