settingFlag = true
}
}
}
}
}
}
处理思路依旧是围绕 onPageScrolled 的参数变化,核心方法为:dealAttrTabViewDynamicSizeWhenScrolling(…), 让当前tabView的文本渐渐变小,而nextTabView的文本逐渐变大。这里如果有疑问可以参照上文的 参数分析小章节。
但是,有一个坑,就是当拖拽停止的时候,viewpager会有一个自动的回弹动作,如果这里没处理好,就会出现,字体大小突变的情况,和我要的平滑动画过渡不相符,所以,这里我做了一个特殊处理,当拖拽停止,也就是手指松开的时候,抓准 ViewPager的 SCROLL_STATE_SETTLING 状态刚刚进入的时机,使用属性动画平滑改变字体,核心代码就是上文代码块中的:indicatorLayout.resetTabViewsStatueByAnimator(indicatorLayout[mCurrentPosition] as GreenTabView)
这句话可以让 tabView的文本字体平滑地从 当前值(不确定,因为dragging状态是用户人为控制),变为 目标值(这是确定值,要么是 正常状态下的字体大小,要么是选中状态下的字体大小),由此完美解决字体平滑变化的问题。
indicatorElastic
滚动时,横条会拉伸和回缩,也是跟随onPageScrolled
的参数变化而变化
关键代码在 SlidingIndicatorLayout.kt
中的 draw方法:
override fun draw(canvas:Canvas?){
…
val baseMultiple = parent.indicatorAttrs.indicatorElasticBaseMultiple // 基础倍数,决定拉伸
val indicatorCriticalValue = 1 + baseMultiple
val ratio =
if (parent.indicatorAttrs.indicatorElastic) {
when {
positionOffset >= 0 && positionOffset < 0.5 -> {
1 + positionOffset * baseMultiple // 拉伸长度
}
else -> {// 如果到了下半段,当offset越过中值之后ratio的值
indicatorCriticalValue - positionOffset * baseMultiple
}
}
} else 1f
// 可以开始绘制
selectedIndicator.run {
setBounds(
((centerX - indicatorWidth * ratio / 2).toInt()),
top,
((centerX + indicatorWidth * ratio / 2).toInt()),
bottom
)// 规定它的边界
draw(canvas!!)// 然后绘制到画布上
}
…
}
这一段提出来特别说明,因为它代表了一种解题思路,我需要的效果是:
viewPager滚动1格,我需要它在滚动一半的时候,横条拉伸到最长,从一半滚完的时候,横条回缩到应该的宽度
但是,viewPager滚1格,positionOffset的变化是从0 到1(手指向右),或者是从1到0(手指向左),我需要把positionOffset在到达0.5的时候当作一个临界时间点,计算出 这个临界时间点上,indicator横条应该的长度。
关键在于:在临界点0.5上,前半段的0->0.5的最终值,必须等于 后半段 0.5->1 的 开始值,
由于我是按照倍数来拉伸,所以,原始倍率是1。我还想用参数控制拉伸的程度,所以设计一个变量 baseMultiple
(拉伸倍数,数值越大,拉伸越明显)
列出公式:
-
前半段的ratio最终值 = 1(
原始倍率
)+ 0.5 *baseMultiple
-
后半段的ratio值 =
indicatorCriticalValue
(临界值
) - 0.5 *baseMultiple
-
前半段的ratio最终值 = 后半段的ratio值
计算得出,indicatorCriticalValue
(临界值) = 1 (原始倍率
)+ baseMultiple
于是就写出了上面的代码。
三阶效果
说了这么多,不如亲眼看一眼效果更佳实在,以上各项属性,下面的动态图基本都有体现, 具体效果可以按需定制,基本可以满足UI姐姐的各种骚操作要求,如果还不行,可以拿我的代码自行修改,我的代码注释应该比谷歌大佬要亲民很多。,欢迎fork,star…
开放无耦合特效接口
为什么生出这种想法?这个是源自:ViewPager的无耦合动画接口。
Viewpager.setPageTransformer(true, MyPageTransformer(this, adapter.count))
viewPager的setPageTransformer,可以传入一个 PageTransformer(接口)的实现类,从而控制ViewPager滑动时的动画,开发者可以自由定制效果,而不用关心ViewPager的内部实现。符合程序设计的开闭法则,让控件开发者和