Tabbar & Viewpager 动效库推荐及浅封

推荐这个库,很好用!

https://github.com/hackware1993/MagicIndicator

基于该库做的封装,以备之后用到

需求有点特别,颜色扩展是为了以备其他页面用到,最重要的是位置扩展,一般的指示器是在底部居中,如下图(该库中的界面):

Tabbar & Viewpager 动效库推荐及浅封_第1张图片
大多都是底部居中

而我们的设计稿是这样的:(靠左居中)


Tabbar & Viewpager 动效库推荐及浅封_第2张图片
滑动起来伸长一倍,而后缩短到原来的样子
Tabbar & Viewpager 动效库推荐及浅封_第3张图片
滑动完毕的样子

所以做了下列扩展,真心说,这个库真不错!扩展也很多!

1 颜色扩展
   /**
     * 设置tab标题的 正常状态 颜色,在 initView() 之前调用,否则不生效
     * 不设置则使用默认颜色
     */
    fun setColorNormal(color: String){
        color_title_normal = color
        invalidate()
    }

    /**
     * 设置tab标题的 选中状态 颜色,在 initView() 之前调用,否则不生效
     * 不设置则使用默认颜色
     */
    fun setColorSelected(color: String){
        color_title_selected = color
        invalidate()
    }

    /**
     * 设置指示器颜色,在 initView() 之前调用,否则不生效
     * 不设置则使用默认颜色
     */
    fun setColorLine(color: String){
        color_line = color
        invalidate()
    }
2 位置扩展 LinePagerIndicator
// 修改了最终绘制的矩形区域,以达到移动的目的
private int transToLeft = 0;
private int transToTop = 0;

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            ...
            this.mLineRect.left = leftX + (nextLeftX - leftX) * this.mStartInterpolator.getInterpolation(positionOffset) + transToLeft;
            this.mLineRect.right = rightX + (nextRightX - rightX) * this.mEndInterpolator.getInterpolation(positionOffset) + transToLeft;
            this.mLineRect.top = (float) this.getHeight() - this.mLineHeight - this.mYOffset + transToTop;
            this.mLineRect.bottom = (float) this.getHeight() - this.mYOffset + transToTop ;
            this.invalidate();
        }
    }

另外要说一下,一开始我打算继承 LinePagerIndicator ,进行修改。

最后发现一个简单方法,聊以记录:

  • 1 找到要修改的文件LinePagerIndicator,因为在jar包中,无法直接修改,
  • 2 可以直接复制该类全部代码,新建一个类并粘贴
  • 3 在使用该类的地方,去除原来jar包中的引用,就可以直接使用新类了
  • 4 现在就可以直接对新建的类进行修改了(我的位置扩展就是在新类中修改的)

代码

1 View封装,暴露设置正常状态与选中状态颜色的方法
/**
 * 
 *     author : jake
 *     time   : 2018/05/08
 *     function   :  动效切换效果的tabView,可以通过传参改变相关颜色及便签内容
 *     version: 1.0
 * 
*/ class AllCourseTabView(context: Context?, attrs: AttributeSet? = null) : MagicIndicator(context, attrs) { // 标题颜色 private var color_title_normal = "#787878" private var color_title_selected = "#180438" // 指示器颜色 private var color_line = "#F5A623" /** * 设置tab标题的 正常状态 颜色,在 initView() 之前调用,否则不生效 * 不设置则使用默认颜色 */ fun setColorNormal(color: String){ color_title_normal = color invalidate() } /** * 设置tab标题的 选中状态 颜色,在 initView() 之前调用,否则不生效 * 不设置则使用默认颜色 */ fun setColorSelected(color: String){ color_title_selected = color invalidate() } /** * 设置指示器颜色,在 initView() 之前调用,否则不生效 * 不设置则使用默认颜色 */ fun setColorLine(color: String){ color_line = color invalidate() } /** * mDataList 指Tab的标签名的集合 */ fun initView(vp:ViewPager,mDataList:List?){ val magicIndicator = findViewById(R.id.tab_all_course) as MagicIndicator magicIndicator.setBackgroundColor(Color.WHITE) val commonNavigator = CommonNavigator(context) commonNavigator.scrollPivotX = 0.65f commonNavigator.adapter = object : CommonNavigatorAdapter() { override fun getCount(): Int { return if (mDataList == null) 0 else mDataList.size } override fun getTitleView(context: Context, index: Int): IPagerTitleView { val simplePagerTitleView = ColorFlipPagerTitleView(context) simplePagerTitleView.text = mDataList!![index] simplePagerTitleView.textSize = 16f simplePagerTitleView.normalColor = Color.parseColor(color_title_normal) simplePagerTitleView.selectedColor = Color.parseColor(color_title_selected) simplePagerTitleView.setOnClickListener { vp.setCurrentItem(index) } return simplePagerTitleView } override fun getIndicator(context: Context): IPagerIndicator { val indicator = LinePagerIndicator(context) indicator.mode = LinePagerIndicator.MODE_EXACTLY indicator.lineHeight = UIUtil.dip2px(context, 4.0).toFloat() indicator.lineWidth = UIUtil.dip2px(context, 36.0).toFloat() indicator.roundRadius = UIUtil.dip2px(context, 2.0).toFloat() indicator.startInterpolator = AccelerateInterpolator() as Interpolator? indicator.endInterpolator = DecelerateInterpolator(2.0f) // 将线条向上移动16,不在底部 indicator.transToLeft = 20.dp indicator.transToTop = 8.dp indicator.setColors(Color.parseColor(color_line)) return indicator } } magicIndicator.navigator = commonNavigator ViewPagerHelper.bind(magicIndicator, vp) } }
2 设置指示器的位置,可以上下左右移动,而不是仅底部居中

/**
 * 
 *     author : jake
 *     time   : 2018/05/08
 *     function   :  暴露getTransToLeft & getTransToTop方法,可以调节指示器的位置(向右或向下输入负值)
 *     version: 1.0
 * 
*/ public class LinePagerIndicator extends View implements IPagerIndicator { public static final int MODE_MATCH_EDGE = 0; public static final int MODE_WRAP_CONTENT = 1; public static final int MODE_EXACTLY = 2; private int mMode; private Interpolator mStartInterpolator = new LinearInterpolator(); private Interpolator mEndInterpolator = new LinearInterpolator(); private float mYOffset; private float mLineHeight; private float mXOffset; private float mLineWidth; private float mRoundRadius; private Paint mPaint; private List mPositionDataList; private List mColors; private RectF mLineRect = new RectF(); private int transToLeft = 0; private int transToTop = 0; public LinePagerIndicator(Context context) { super(context); this.init(context); } private void init(Context context) { this.mPaint = new Paint(1); this.mPaint.setStyle(Style.FILL); this.mLineHeight = (float) UIUtil.dip2px(context, 3.0D); this.mLineWidth = (float) UIUtil.dip2px(context, 10.0D); } protected void onDraw(Canvas canvas) { canvas.drawRoundRect(this.mLineRect, this.mRoundRadius, this.mRoundRadius, this.mPaint); } public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (this.mPositionDataList != null && !this.mPositionDataList.isEmpty()) { if (this.mColors != null && this.mColors.size() > 0) { int currentColor = (Integer) this.mColors.get(Math.abs(position) % this.mColors.size()); int nextColor = (Integer) this.mColors.get(Math.abs(position + 1) % this.mColors.size()); int color = ArgbEvaluatorHolder.eval(positionOffset, currentColor, nextColor); this.mPaint.setColor(color); } PositionData current = FragmentContainerHelper.getImitativePositionData(this.mPositionDataList, position); PositionData next = FragmentContainerHelper.getImitativePositionData(this.mPositionDataList, position + 1); float nextLeftX; float rightX; float nextRightX; float leftX; if (this.mMode == 0) { leftX = (float) current.mLeft + this.mXOffset; nextLeftX = (float) next.mLeft + this.mXOffset; rightX = (float) current.mRight - this.mXOffset; nextRightX = (float) next.mRight - this.mXOffset; } else if (this.mMode == 1) { leftX = (float) current.mContentLeft + this.mXOffset; nextLeftX = (float) next.mContentLeft + this.mXOffset; rightX = (float) current.mContentRight - this.mXOffset; nextRightX = (float) next.mContentRight - this.mXOffset; } else { leftX = (float) current.mLeft + ((float) current.width() - this.mLineWidth) / 2.0F; nextLeftX = (float) next.mLeft + ((float) next.width() - this.mLineWidth) / 2.0F; rightX = (float) current.mLeft + ((float) current.width() + this.mLineWidth) / 2.0F; nextRightX = (float) next.mLeft + ((float) next.width() + this.mLineWidth) / 2.0F; } this.mLineRect.left = leftX + (nextLeftX - leftX) * this.mStartInterpolator.getInterpolation(positionOffset) + transToLeft; this.mLineRect.right = rightX + (nextRightX - rightX) * this.mEndInterpolator.getInterpolation(positionOffset) + transToLeft; this.mLineRect.top = (float) this.getHeight() - this.mLineHeight - this.mYOffset + transToTop; this.mLineRect.bottom = (float) this.getHeight() - this.mYOffset + transToTop ; this.invalidate(); } } public void onPageSelected(int position) { } public void onPageScrollStateChanged(int state) { } public void onPositionDataProvide(List dataList) { this.mPositionDataList = dataList; } public float getYOffset() { return this.mYOffset; } public void setYOffset(float yOffset) { this.mYOffset = yOffset; } public float getXOffset() { return this.mXOffset; } public void setXOffset(float xOffset) { this.mXOffset = xOffset; } public float getLineHeight() { return this.mLineHeight; } public void setLineHeight(float lineHeight) { this.mLineHeight = lineHeight; } public float getLineWidth() { return this.mLineWidth; } public void setLineWidth(float lineWidth) { this.mLineWidth = lineWidth; } public float getRoundRadius() { return this.mRoundRadius; } public void setRoundRadius(float roundRadius) { this.mRoundRadius = roundRadius; } public int getMode() { return this.mMode; } public int getTransToLeft() { return transToLeft; } public void setTransToLeft(int transToLeft) { this.transToLeft = transToLeft*(-1); } public int getTransToTop() { return transToTop; } public void setTransToTop(int transToTop) { this.transToTop = transToTop*(-1); } public void setMode(int mode) { if (mode != 2 && mode != 0 && mode != 1) { throw new IllegalArgumentException("mode " + mode + " not supported."); } else { this.mMode = mode; } } public Paint getPaint() { return this.mPaint; } public List getColors() { return this.mColors; } public void setColors(Integer... colors) { this.mColors = Arrays.asList(colors); } public Interpolator getStartInterpolator() { return this.mStartInterpolator; } public void setStartInterpolator(Interpolator startInterpolator) { this.mStartInterpolator = startInterpolator; if (this.mStartInterpolator == null) { this.mStartInterpolator = new LinearInterpolator(); } } public Interpolator getEndInterpolator() { return this.mEndInterpolator; } public void setEndInterpolator(Interpolator endInterpolator) { this.mEndInterpolator = endInterpolator; if (this.mEndInterpolator == null) { this.mEndInterpolator = new LinearInterpolator(); } } }

你可能感兴趣的:(Tabbar & Viewpager 动效库推荐及浅封)