diff --git a/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/CommonTabLayout.java b/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/CommonTabLayout.java index 6bea6c51..cdbd16f8 100644 --- a/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/CommonTabLayout.java +++ b/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/CommonTabLayout.java @@ -11,6 +11,7 @@ import android.os.Bundle; import android.os.Parcelable; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.util.AttributeSet; import android.util.Log; @@ -73,12 +74,12 @@ public class CommonTabLayout extends FrameLayout implements ValueAnimator.Animat private long indicatorAnimDuration; private boolean indicatorAnimEnable; private boolean indicatorBounceEnable; - private float indicatorGravity; + private int indicatorGravity; /** underline */ private int underlineColor; private float underlineHeight; - private float underlineGravity; + private int underlineGravity; /** divider */ private int dividerColor; @@ -148,7 +149,7 @@ private void obtainAttributes(Context context, AttributeSet attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CommonTabLayout); indicatorStyle = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_style, 0); - indicatorColor = ta.getColor(R.styleable.CommonTabLayout_tl_indicator_color, Color.parseColor(indicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff")); + indicatorColor = ta.getColor(R.styleable.CommonTabLayout_tl_indicator_color, Color.parseColor(indicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff")); indicatorHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_height, dp2px(indicatorStyle == STYLE_TRIANGLE ? 4 : (indicatorStyle == STYLE_BLOCK ? -1 : 2))); indicatorWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_width, dp2px(indicatorStyle == STYLE_TRIANGLE ? 10 : -1)); @@ -201,8 +202,8 @@ public void setTabData(ArrayList tabEntitys) { } /** 关联数据支持同时切换fragments */ - public void setTabData(ArrayList tabEntitys, FragmentManager fm, int containerViewId, ArrayList fragments) { - fragmentChangeManager = new FragmentChangeManager(fm, containerViewId, fragments); + public void setTabData(ArrayList tabEntitys, FragmentActivity fa, int containerViewId, ArrayList fragments) { + fragmentChangeManager = new FragmentChangeManager(fa.getSupportFragmentManager(), containerViewId, fragments); setTabData(tabEntitys); } @@ -390,7 +391,7 @@ protected void onDraw(Canvas canvas) { dividerPaint.setColor(dividerColor); for (int i = 0; i < tabCount - 1; i++) { View tab = tabsContainer.getChildAt(i); - canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); + canvas.drawLine(paddingLeft + tab.getRight(), dividerPadding, paddingLeft + tab.getRight(), height - dividerPadding, dividerPaint); } } @@ -524,13 +525,8 @@ public void setIndicatorCornerRadius(float indicatorCornerRadius) { invalidate(); } - public void setUnderlineColor(int underlineColor) { - this.underlineColor = underlineColor; - invalidate(); - } - - public void setUnderlineHeight(float underlineHeight) { - this.underlineHeight = dp2px(underlineHeight); + public void setIndicatorGravity(int indicatorGravity) { + this.indicatorGravity = indicatorGravity; invalidate(); } @@ -555,6 +551,21 @@ public void setIndicatorBounceEnable(boolean indicatorBounceEnable) { this.indicatorBounceEnable = indicatorBounceEnable; } + public void setUnderlineColor(int underlineColor) { + this.underlineColor = underlineColor; + invalidate(); + } + + public void setUnderlineHeight(float underlineHeight) { + this.underlineHeight = dp2px(underlineHeight); + invalidate(); + } + + public void setUnderlineGravity(int underlineGravity) { + this.underlineGravity = underlineGravity; + invalidate(); + } + public void setDividerColor(int dividerColor) { this.dividerColor = dividerColor; invalidate(); diff --git a/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/SegmentTabLayout.java b/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/SegmentTabLayout.java new file mode 100644 index 00000000..3506083d --- /dev/null +++ b/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/SegmentTabLayout.java @@ -0,0 +1,632 @@ +package com.flyco.tablayout; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.GradientDrawable; +import android.os.Bundle; +import android.os.Parcelable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.View; +import android.view.animation.OvershootInterpolator; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.flyco.tablayout.listener.OnTabSelectListener; +import com.flyco.tablayout.utils.FragmentChangeManager; +import com.nineoldandroids.animation.TypeEvaluator; +import com.nineoldandroids.animation.ValueAnimator; + +import java.util.ArrayList; + +public class SegmentTabLayout extends FrameLayout implements ValueAnimator.AnimatorUpdateListener { + private Context context; + private String[] titles; + private LinearLayout tabsContainer; + private int currentTab; + private int lastTab; + private int tabCount; + /** 用于绘制显示器 */ + private Rect indicatorRect = new Rect(); + private GradientDrawable indicatorDrawable = new GradientDrawable(); + private GradientDrawable rectDrawable = new GradientDrawable(); + + private Paint dividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + private float tabPadding; + private boolean tabSpaceEqual; + private float tabWidth; + + /** indicator */ + private int indicatorColor; + private float indicatorHeight; + private float indicatorCornerRadius; + private float indicatorMarginLeft; + private float indicatorMarginTop; + private float indicatorMarginRight; + private float indicatorMarginBottom; + private long indicatorAnimDuration; + private boolean indicatorAnimEnable; + private boolean indicatorBounceEnable; + + /** divider */ + private int dividerColor; + private float dividerWidth; + private float dividerPadding; + + /** title */ + private float textsize; + private int textSelectColor; + private int textUnselectColor; + private boolean textBold; + private boolean textAllCaps; + + private int barColor; + private int barStrokeColor; + private float barStrokeWidth; + + /** anim */ + private ValueAnimator valueAnimator; + private OvershootInterpolator interpolator = new OvershootInterpolator(0.8f); + + private FragmentChangeManager fragmentChangeManager; + private float[] radiusArr = new float[8]; + + public SegmentTabLayout(Context context) { + this(context, null, 0); + } + + public SegmentTabLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SegmentTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setWillNotDraw(false);//重写onDraw方法,需要调用这个方法来清除flag + setClipChildren(false); + setClipToPadding(false); + + this.context = context; + tabsContainer = new LinearLayout(context); + addView(tabsContainer); + + obtainAttributes(context, attrs); + + valueAnimator = ValueAnimator.ofObject(new PointEvaluator(), lp, cp); + valueAnimator.addUpdateListener(this); + } + + private void obtainAttributes(Context context, AttributeSet attrs) { + TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SegmentTabLayout); + + indicatorColor = ta.getColor(R.styleable.SegmentTabLayout_tl_indicator_color, Color.parseColor("#222831")); + indicatorHeight = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_height, -1); + indicatorCornerRadius = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_corner_radius, -1); + indicatorMarginLeft = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_left, dp2px(0)); + indicatorMarginTop = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_top, 0); + indicatorMarginRight = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_right, dp2px(0)); + indicatorMarginBottom = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_bottom, 0); + indicatorAnimEnable = ta.getBoolean(R.styleable.SegmentTabLayout_tl_indicator_anim_enable, false); + indicatorBounceEnable = ta.getBoolean(R.styleable.SegmentTabLayout_tl_indicator_bounce_enable, true); + indicatorAnimDuration = ta.getInt(R.styleable.SegmentTabLayout_tl_indicator_anim_duration, -1); + + dividerColor = ta.getColor(R.styleable.SegmentTabLayout_tl_divider_color, indicatorColor); + dividerWidth = ta.getDimension(R.styleable.SegmentTabLayout_tl_divider_width, dp2px(1)); + dividerPadding = ta.getDimension(R.styleable.SegmentTabLayout_tl_divider_padding, 0); + + textsize = ta.getDimension(R.styleable.SegmentTabLayout_tl_textsize, sp2px(13f)); + textSelectColor = ta.getColor(R.styleable.SegmentTabLayout_tl_textSelectColor, Color.parseColor("#ffffff")); + textUnselectColor = ta.getColor(R.styleable.SegmentTabLayout_tl_textUnselectColor, indicatorColor); + textBold = ta.getBoolean(R.styleable.SegmentTabLayout_tl_textBold, false); + textAllCaps = ta.getBoolean(R.styleable.SegmentTabLayout_tl_textAllCaps, false); + + tabSpaceEqual = ta.getBoolean(R.styleable.SegmentTabLayout_tl_tab_space_equal, true); + tabWidth = ta.getDimension(R.styleable.SegmentTabLayout_tl_tab_width, dp2px(-1)); + tabPadding = ta.getDimension(R.styleable.SegmentTabLayout_tl_tab_padding, tabSpaceEqual || tabWidth > 0 ? dp2px(0) : dp2px(10)); + + barColor = ta.getColor(R.styleable.SegmentTabLayout_tl_bar_color, Color.TRANSPARENT); + barStrokeColor = ta.getColor(R.styleable.SegmentTabLayout_tl_bar_stroke_color, indicatorColor); + barStrokeWidth = ta.getDimension(R.styleable.SegmentTabLayout_tl_bar_stroke_width, dp2px(1)); + + ta.recycle(); + } + + public void setTabData(String[] titles) { + if (titles == null || titles.length == 0) { + throw new IllegalStateException("Titles can not be NULL or EMPTY !"); + } + + this.titles = titles; + + notifyDataSetChanged(); + } + + /** 关联数据支持同时切换fragments */ + public void setTabData(String[] titles, FragmentActivity fa, int containerViewId, ArrayList fragments) { + fragmentChangeManager = new FragmentChangeManager(fa.getSupportFragmentManager(), containerViewId, fragments); + setTabData(titles); + } + + /** 更新数据 */ + public void notifyDataSetChanged() { + tabsContainer.removeAllViews(); + this.tabCount = titles.length; + View tabView; + for (int i = 0; i < tabCount; i++) { + tabView = View.inflate(context, R.layout.layout_tab, 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(titles[position]); + + tabView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + int position = (Integer) v.getTag(); + if (currentTab != position) { + isFirstSet = false; + setCurrentTab(position); + if (listener != null) { + listener.onTabSelect(position); + } + } else { + if (listener != null) { + listener.onTabReselect(position); + } + } + } + }); + + /** 每一个Tab的布局参数 */ + LinearLayout.LayoutParams lp_tab = tabSpaceEqual ? + new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) : + new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); + if (tabWidth > 0) { + lp_tab = new LinearLayout.LayoutParams((int) tabWidth, LayoutParams.MATCH_PARENT); + } + tabsContainer.addView(tabView, position, lp_tab); + } + + private void updateTabStyles() { + for (int i = 0; i < tabCount; i++) { + View tabView = tabsContainer.getChildAt(i); + tabView.setPadding((int) tabPadding, 0, (int) tabPadding, 0); + TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title); + tv_tab_title.setTextColor(i == currentTab ? textSelectColor : textUnselectColor); + tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, textsize); +// tv_tab_title.setPadding((int) tabPadding, 0, (int) tabPadding, 0); + if (textAllCaps) { + tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase()); + } + + if (textBold) { + tv_tab_title.getPaint().setFakeBoldText(textBold); + } + } + } + + private void updateTabSelection(int position) { + for (int i = 0; i < tabCount; ++i) { + View tabView = tabsContainer.getChildAt(i); + final boolean isSelect = i == position; + TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title); + tab_title.setTextColor(isSelect ? textSelectColor : textUnselectColor); + } + } + + private void calcOffset() { + final View currentTabView = tabsContainer.getChildAt(this.currentTab); + cp.left = currentTabView.getLeft(); + cp.right = currentTabView.getRight(); + + final View lastTabView = tabsContainer.getChildAt(this.lastTab); + lp.left = lastTabView.getLeft(); + lp.right = lastTabView.getRight(); + + valueAnimator.setObjectValues(lp, cp); + if (indicatorBounceEnable) { + valueAnimator.setInterpolator(interpolator); + } + + if (indicatorAnimDuration < 0) { + indicatorAnimDuration = indicatorBounceEnable ? 500 : 250; + } + valueAnimator.setDuration(indicatorAnimDuration); + valueAnimator.start(); + } + + private void calcIndicatorRect() { + View currentTabView = tabsContainer.getChildAt(this.currentTab); + float left = currentTabView.getLeft(); + float right = currentTabView.getRight(); + + indicatorRect.left = (int) left; + indicatorRect.right = (int) right; + + if (!indicatorAnimEnable) { + if (currentTab == 0) { + /**The corners are ordered top-left, top-right, bottom-right, bottom-left*/ + radiusArr[0] = indicatorCornerRadius; + radiusArr[1] = indicatorCornerRadius; + radiusArr[2] = 0; + radiusArr[3] = 0; + radiusArr[4] = 0; + radiusArr[5] = 0; + radiusArr[6] = indicatorCornerRadius; + radiusArr[7] = indicatorCornerRadius; + } else if (currentTab == tabCount - 1) { + /**The corners are ordered top-left, top-right, bottom-right, bottom-left*/ + radiusArr[0] = 0; + radiusArr[1] = 0; + radiusArr[2] = indicatorCornerRadius; + radiusArr[3] = indicatorCornerRadius; + radiusArr[4] = indicatorCornerRadius; + radiusArr[5] = indicatorCornerRadius; + radiusArr[6] = 0; + radiusArr[7] = 0; + } else { + /**The corners are ordered top-left, top-right, bottom-right, bottom-left*/ + radiusArr[0] = 0; + radiusArr[1] = 0; + radiusArr[2] = 0; + radiusArr[3] = 0; + radiusArr[4] = 0; + radiusArr[5] = 0; + radiusArr[6] = 0; + radiusArr[7] = 0; + } + } else { + /**The corners are ordered top-left, top-right, bottom-right, bottom-left*/ + radiusArr[0] = indicatorCornerRadius; + radiusArr[1] = indicatorCornerRadius; + radiusArr[2] = indicatorCornerRadius; + radiusArr[3] = indicatorCornerRadius; + radiusArr[4] = indicatorCornerRadius; + radiusArr[5] = indicatorCornerRadius; + radiusArr[6] = indicatorCornerRadius; + radiusArr[7] = indicatorCornerRadius; + } + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + IndicatorPoint p = (IndicatorPoint) animation.getAnimatedValue(); + indicatorRect.left = (int) p.left; + indicatorRect.right = (int) p.right; + invalidate(); + } + + private boolean isFirstDraw = true; + private boolean isFirstSet = true; + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (isInEditMode() || tabCount <= 0) { + return; + } + + int height = getHeight(); + int paddingLeft = getPaddingLeft(); + + if (indicatorHeight < 0) { + indicatorHeight = height - indicatorMarginTop - indicatorMarginBottom; + } + + if (indicatorCornerRadius < 0 || indicatorCornerRadius > indicatorHeight / 2) { + indicatorCornerRadius = indicatorHeight / 2; + } + + //draw rect + rectDrawable.setColor(barColor); + rectDrawable.setStroke((int) barStrokeWidth, barStrokeColor); + rectDrawable.setCornerRadius(indicatorCornerRadius); + rectDrawable.setBounds(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom()); + rectDrawable.draw(canvas); + + // draw divider + if (!indicatorAnimEnable && dividerWidth > 0) { + dividerPaint.setStrokeWidth(dividerWidth); + dividerPaint.setColor(dividerColor); + for (int i = 0; i < tabCount - 1; i++) { + View tab = tabsContainer.getChildAt(i); + canvas.drawLine(paddingLeft + tab.getRight(), dividerPadding, paddingLeft + tab.getRight(), height - dividerPadding, dividerPaint); + } + } + + + //draw indicator line + if (indicatorAnimEnable) { + if (isFirstDraw) { + isFirstDraw = false; + calcIndicatorRect(); + } + } else { + calcIndicatorRect(); + } + + indicatorDrawable.setColor(indicatorColor); + indicatorDrawable.setBounds(paddingLeft + (int) indicatorMarginLeft + indicatorRect.left, + (int) indicatorMarginTop, (int) (paddingLeft + indicatorRect.right - indicatorMarginRight), + (int) (indicatorMarginTop + indicatorHeight)); + indicatorDrawable.setCornerRadii(radiusArr); + indicatorDrawable.draw(canvas); + + } + + //setter and getter + public void setCurrentTab(int currentTab) { + lastTab = this.currentTab; + this.currentTab = currentTab; + updateTabSelection(currentTab); + if (fragmentChangeManager != null) { + fragmentChangeManager.setFragments(currentTab); + } + if (indicatorAnimEnable) { + if (isFirstSet) { + invalidate(); + isFirstSet = false; + } else { + calcOffset(); + } + } else { + invalidate(); + } + } + + public void setTabPadding(float tabPadding) { + this.tabPadding = dp2px(tabPadding); + updateTabStyles(); + } + + public void setTabSpaceEqual(boolean tabSpaceEqual) { + this.tabSpaceEqual = tabSpaceEqual; + updateTabStyles(); + } + + public void setTabWidth(float tabWidth) { + this.tabWidth = dp2px(tabWidth); + updateTabStyles(); + } + + public void setIndicatorColor(int indicatorColor) { + this.indicatorColor = indicatorColor; + invalidate(); + } + + public void setIndicatorHeight(float indicatorHeight) { + this.indicatorHeight = dp2px(indicatorHeight); + invalidate(); + } + + public void setIndicatorCornerRadius(float indicatorCornerRadius) { + this.indicatorCornerRadius = dp2px(indicatorCornerRadius); + invalidate(); + } + + public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop, + float indicatorMarginRight, float indicatorMarginBottom) { + this.indicatorMarginLeft = dp2px(indicatorMarginLeft); + this.indicatorMarginTop = dp2px(indicatorMarginTop); + this.indicatorMarginRight = dp2px(indicatorMarginRight); + this.indicatorMarginBottom = dp2px(indicatorMarginBottom); + invalidate(); + } + + public void setIndicatorAnimDuration(long indicatorAnimDuration) { + this.indicatorAnimDuration = indicatorAnimDuration; + } + + public void setIndicatorAnimEnable(boolean indicatorAnimEnable) { + this.indicatorAnimEnable = indicatorAnimEnable; + } + + public void setIndicatorBounceEnable(boolean indicatorBounceEnable) { + this.indicatorBounceEnable = indicatorBounceEnable; + } + + public void setDividerColor(int dividerColor) { + this.dividerColor = dividerColor; + invalidate(); + } + + public void setDividerWidth(float dividerWidth) { + this.dividerWidth = dp2px(dividerWidth); + invalidate(); + } + + public void setDividerPadding(float dividerPadding) { + this.dividerPadding = dp2px(dividerPadding); + invalidate(); + } + + public void setTextsize(float textsize) { + this.textsize = sp2px(textsize); + updateTabStyles(); + } + + public void setTextSelectColor(int textSelectColor) { + this.textSelectColor = textSelectColor; + updateTabStyles(); + } + + public void setTextUnselectColor(int textUnselectColor) { + this.textUnselectColor = textUnselectColor; + updateTabStyles(); + } + + public void setTextBold(boolean textBold) { + this.textBold = textBold; + updateTabStyles(); + } + + public void setTextAllCaps(boolean textAllCaps) { + this.textAllCaps = textAllCaps; + updateTabStyles(); + } + + public int getTabCount() { + return tabCount; + } + + public int getCurrentTab() { + return currentTab; + } + + public float getTabPadding() { + return tabPadding; + } + + public boolean isTabSpaceEqual() { + return tabSpaceEqual; + } + + public float getTabWidth() { + return tabWidth; + } + + public int getIndicatorColor() { + return indicatorColor; + } + + public float getIndicatorHeight() { + return indicatorHeight; + } + + public float getIndicatorCornerRadius() { + return indicatorCornerRadius; + } + + public float getIndicatorMarginLeft() { + return indicatorMarginLeft; + } + + public float getIndicatorMarginTop() { + return indicatorMarginTop; + } + + public float getIndicatorMarginRight() { + return indicatorMarginRight; + } + + public float getIndicatorMarginBottom() { + return indicatorMarginBottom; + } + + public long getIndicatorAnimDuration() { + return indicatorAnimDuration; + } + + public boolean isIndicatorAnimEnable() { + return indicatorAnimEnable; + } + + public boolean isIndicatorBounceEnable() { + return indicatorBounceEnable; + } + + public int getDividerColor() { + return dividerColor; + } + + public float getDividerWidth() { + return dividerWidth; + } + + public float getDividerPadding() { + return dividerPadding; + } + + public float getTextsize() { + return textsize; + } + + public int getTextSelectColor() { + return textSelectColor; + } + + public int getTextUnselectColor() { + return textUnselectColor; + } + + public boolean isTextBold() { + return textBold; + } + + public boolean isTextAllCaps() { + return textAllCaps; + } + + //setter and getter + private OnTabSelectListener listener; + + public void setOnTabSelectListener(OnTabSelectListener listener) { + this.listener = listener; + } + + @Override + protected Parcelable onSaveInstanceState() { + Bundle bundle = new Bundle(); + bundle.putParcelable("instanceState", super.onSaveInstanceState()); + bundle.putInt("currentTab", currentTab); + return bundle; + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + if (state instanceof Bundle) { + Bundle bundle = (Bundle) state; + currentTab = bundle.getInt("currentTab"); + state = bundle.getParcelable("instanceState"); + if (currentTab != 0 && tabsContainer.getChildCount() > 0) { + updateTabSelection(currentTab); + } + } + super.onRestoreInstanceState(state); + } + + class IndicatorPoint { + public float left; + public float right; + } + + private IndicatorPoint cp = new IndicatorPoint(); + private IndicatorPoint lp = new IndicatorPoint(); + + class PointEvaluator implements TypeEvaluator { + @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 = context.getResources().getDisplayMetrics().density; + return (int) (dp * scale + 0.5f); + } + + protected int sp2px(float sp) { + final float scale = this.context.getResources().getDisplayMetrics().scaledDensity; + return (int) (sp * scale + 0.5f); + } +} diff --git a/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/SlidingTabLayout.java b/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/SlidingTabLayout.java index 29ef4dcb..19ae1c14 100644 --- a/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/SlidingTabLayout.java +++ b/FlycoTabLayout_Lib/src/main/java/com/flyco/tablayout/SlidingTabLayout.java @@ -69,13 +69,13 @@ public class SlidingTabLayout extends HorizontalScrollView implements ViewPager. private float indicatorMarginTop; private float indicatorMarginRight; private float indicatorMarginBottom; - private float indicatorGravity; + private int indicatorGravity; private boolean indicatorWidthEqualTitle; /** underline */ private int underlineColor; private float underlineHeight; - private float underlineGravity; + private int underlineGravity; /** divider */ private int dividerColor; @@ -433,7 +433,7 @@ protected void onDraw(Canvas canvas) { dividerPaint.setColor(dividerColor); for (int i = 0; i < tabCount - 1; i++) { View tab = tabsContainer.getChildAt(i); - canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); + canvas.drawLine(paddingLeft + tab.getRight(), dividerPadding, paddingLeft + tab.getRight(), height - dividerPadding, dividerPaint); } } @@ -551,21 +551,11 @@ public void setIndicatorCornerRadius(float indicatorCornerRadius) { invalidate(); } - public void setIndicatorGravity(float indicatorGravity) { + public void setIndicatorGravity(int indicatorGravity) { this.indicatorGravity = indicatorGravity; invalidate(); } - public void setUnderlineColor(int underlineColor) { - this.underlineColor = underlineColor; - invalidate(); - } - - public void setUnderlineHeight(float underlineHeight) { - this.underlineHeight = dp2px(underlineHeight); - invalidate(); - } - public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop, float indicatorMarginRight, float indicatorMarginBottom) { this.indicatorMarginLeft = dp2px(indicatorMarginLeft); @@ -580,7 +570,17 @@ public void setIndicatorWidthEqualTitle(boolean indicatorWidthEqualTitle) { invalidate(); } - public void setUnderlineGravity(float underlineGravity) { + public void setUnderlineColor(int underlineColor) { + this.underlineColor = underlineColor; + invalidate(); + } + + public void setUnderlineHeight(float underlineHeight) { + this.underlineHeight = dp2px(underlineHeight); + invalidate(); + } + + public void setUnderlineGravity(int underlineGravity) { this.underlineGravity = underlineGravity; invalidate(); } diff --git a/FlycoTabLayout_Lib/src/main/res/values/attrs.xml b/FlycoTabLayout_Lib/src/main/res/values/attrs.xml index 7fd53cdb..81ac8519 100644 --- a/FlycoTabLayout_Lib/src/main/res/values/attrs.xml +++ b/FlycoTabLayout_Lib/src/main/res/values/attrs.xml @@ -27,6 +27,12 @@ + + + + + + @@ -117,12 +123,9 @@ - - - - - - + + + @@ -164,4 +167,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index adec9722..b9a3f790 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,9 @@ + diff --git a/app/src/main/java/com/flyco/tablayoutsamples/ui/CommonTabActivity.java b/app/src/main/java/com/flyco/tablayoutsamples/ui/CommonTabActivity.java index eb12184e..e4b66796 100644 --- a/app/src/main/java/com/flyco/tablayoutsamples/ui/CommonTabActivity.java +++ b/app/src/main/java/com/flyco/tablayoutsamples/ui/CommonTabActivity.java @@ -83,7 +83,7 @@ protected void onCreate(Bundle savedInstanceState) { tl_1.setTabData(tabs); tl_2(); - tl_3.setTabData(tabs, getSupportFragmentManager(), R.id.fl_change, fragments2); + tl_3.setTabData(tabs, this, R.id.fl_change, fragments2); tl_4.setTabData(tabs); tl_5.setTabData(tabs); tl_6.setTabData(tabs); diff --git a/app/src/main/java/com/flyco/tablayoutsamples/ui/SegmentTabActivity.java b/app/src/main/java/com/flyco/tablayoutsamples/ui/SegmentTabActivity.java new file mode 100644 index 00000000..9cc919b9 --- /dev/null +++ b/app/src/main/java/com/flyco/tablayoutsamples/ui/SegmentTabActivity.java @@ -0,0 +1,199 @@ +package com.flyco.tablayoutsamples.ui; + +import android.content.Context; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; +import android.view.View; + +import com.flyco.tablayout.SegmentTabLayout; +import com.flyco.tablayout.listener.CustomTabEntity; +import com.flyco.tablayout.listener.OnTabSelectListener; +import com.flyco.tablayoutsamples.R; +import com.flyco.tablayoutsamples.entity.TabEntity; +import com.flyco.tablayoutsamples.utils.ViewFindUtils; + +import java.util.ArrayList; + +public class SegmentTabActivity extends AppCompatActivity { + private Context context = this; + private ArrayList fragments = new ArrayList<>(); + private ArrayList fragments2 = new ArrayList<>(); + + private String[] titles = {"首页", "消息"}; + private String[] titles_2 = {"首页", "消息", "联系人"}; + private String[] titles_3 = {"首页", "消息", "联系人", "更多"}; + private int[] iconUnselectIds = { + R.mipmap.tab_home_unselect, R.mipmap.tab_speech_unselect, + R.mipmap.tab_contact_unselect, R.mipmap.tab_more_unselect}; + private int[] iconSelectIds = { + R.mipmap.tab_home_select, R.mipmap.tab_speech_select, + R.mipmap.tab_contact_select, R.mipmap.tab_more_select}; + private ArrayList tabs = new ArrayList<>(); + private View decorView; + private SegmentTabLayout tl_3; + // private CommonTabLayout tl_4; +// private CommonTabLayout tl_5; +// private CommonTabLayout tl_6; +// private CommonTabLayout tl_7; +// private CommonTabLayout tl_8; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_segment_tab); + + for (String title : titles_2) { + fragments2.add(SimpleCardFragment.getInstance("Switch Fragment " + title)); + } + + for (String title : titles_3) { + fragments.add(SimpleCardFragment.getInstance("Switch ViewPager " + title)); + } + + + for (int i = 0; i < titles.length; i++) { + tabs.add(new TabEntity(titles[i], iconSelectIds[i], iconUnselectIds[i])); + } + + decorView = getWindow().getDecorView(); + + SegmentTabLayout tl_1 = ViewFindUtils.find(decorView, R.id.tl_1); + SegmentTabLayout tl_2 = ViewFindUtils.find(decorView, R.id.tl_2); + tl_3 = ViewFindUtils.find(decorView, R.id.tl_3); + SegmentTabLayout tl_4 = ViewFindUtils.find(decorView, R.id.tl_4); + SegmentTabLayout tl_5 = ViewFindUtils.find(decorView, R.id.tl_5); + + tl_1.setTabData(titles); + tl_2.setTabData(titles_2); + tl_3(); + tl_4.setTabData(titles_2, this, R.id.fl_change, fragments2); + tl_5.setTabData(titles_3); +// /** indicator固定宽度 */ +// tl_5 = ViewFindUtils.find(decorView, R.id.tl_5); +// /** indicator矩形圆角 */ +// tl_6 = ViewFindUtils.find(decorView, R.id.tl_6); +// /** indicator三角形 */ +// tl_7 = ViewFindUtils.find(decorView, R.id.tl_7); +// /** indicator圆角色块 */ +// tl_8 = ViewFindUtils.find(decorView, R.id.tl_8); + + +// tl_3.setTabData(tabs, this, R.id.fl_change, fragments2); +// tl_4.setTabData(tabs); +// tl_5.setTabData(tabs); +// tl_6.setTabData(tabs); +// tl_7.setTabData(tabs); +// tl_8.setTabData(tabs); +// +// tl_3.setOnTabSelectListener(new OnTabSelectListener() { +// @Override +// public void onTabSelect(int position) { +// tl_1.setCurrentTab(position); +// tl_3.setCurrentTab(position); +// tl_4.setCurrentTab(position); +// tl_5.setCurrentTab(position); +// tl_6.setCurrentTab(position); +// tl_7.setCurrentTab(position); +// tl_8.setCurrentTab(position); +// } +// +// @Override +// public void onTabReselect(int position) { +// +// } +// }); +// +// //显示未读红点 +// tl_1.showDot(2); +// tl_3.showDot(1); +// tl_4.showDot(1); +// +// //两位数 +// tl_3.showMsg(0, 55); +// tl_3.setMsgMargin(0, -5, 5); +// +// //三位数 +// tl_3.showMsg(1, 100); +// tl_3.setMsgMargin(1, -5, 5); +// +// //设置未读消息红点 +// tl_3.showDot(2); +// RoundTextView rtv_2_2 = tl_3.getMsgView(2); +// if (rtv_2_2 != null) { +// rtv_2_2.setWidth(dp2px(7.5f)); +// } +// +// //设置未读消息背景 +// tl_3.showMsg(3, 5); +// tl_3.setMsgMargin(3, 0, 5); +// RoundTextView rtv_2_3 = tl_3.getMsgView(3); +// if (rtv_2_3 != null) { +// rtv_2_3.getDelegate().setBackgroundColor(Color.parseColor("#6D8FB0")); +// } + } + + private void tl_3() { + final ViewPager vp_3 = ViewFindUtils.find(decorView, R.id.vp_2); + vp_3.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); + + tl_3.setTabData(titles_3); + tl_3.setOnTabSelectListener(new OnTabSelectListener() { + @Override + public void onTabSelect(int position) { + vp_3.setCurrentItem(position); + } + + @Override + public void onTabReselect(int position) { + } + }); + + vp_3.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + tl_3.setCurrentTab(position); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + vp_3.setCurrentItem(1); + } + + private class MyPagerAdapter extends FragmentPagerAdapter { + public MyPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return fragments.size(); + } + + @Override + public CharSequence getPageTitle(int position) { + return titles_3[position]; + } + + @Override + public Fragment getItem(int position) { + return fragments.get(position); + } + } + + protected int dp2px(float dp) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dp * scale + 0.5f); + } +} diff --git a/app/src/main/java/com/flyco/tablayoutsamples/ui/SimpleHomeActivity.java b/app/src/main/java/com/flyco/tablayoutsamples/ui/SimpleHomeActivity.java index 5c38cb89..805c2fac 100644 --- a/app/src/main/java/com/flyco/tablayoutsamples/ui/SimpleHomeActivity.java +++ b/app/src/main/java/com/flyco/tablayoutsamples/ui/SimpleHomeActivity.java @@ -9,12 +9,14 @@ import android.widget.AdapterView; import android.widget.ListView; +import com.flyco.tablayout.SegmentTabLayout; import com.flyco.tablayoutsamples.adapter.SimpleHomeAdapter; public class SimpleHomeActivity extends AppCompatActivity { private Context context = this; - private final String[] items = {"SlidingTabLayout", "CommonTabLayout"}; - private final Class[] classes = {SlidingTabActivity.class, CommonTabActivity.class}; + private final String[] items = {"SlidingTabLayout", "CommonTabLayout", "SegmentTabLayout"}; + private final Class[] classes = {SlidingTabActivity.class, CommonTabActivity.class, + SegmentTabActivity.class}; @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/app/src/main/res/layout/activity_segment_tab.xml b/app/src/main/res/layout/activity_segment_tab.xml new file mode 100644 index 00000000..61d680af --- /dev/null +++ b/app/src/main/res/layout/activity_segment_tab.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file