抛物线效果最主要的难点和原理在于贝塞尔曲线动画的生成,我们通过图片主要讲解贝塞尔曲线动画,这里用到的是二级贝塞尔曲线
1、需要找到贝塞尔曲线的三个点,开启点、结束点、控制点
2、通过二级贝塞尔曲线的公式计算,获取贝塞尔曲线的轨迹路径点
3、通过设置点赞图片X,Y坐标,从而形成点赞的效果
1、初始化变量
class BezIEr2Layout : relativeLayout, VIEw.OnClickListener { private var startPoint = Point(0, 0) private var endPoint = Point(0, 0) private var controlPoint = Point(0, 0) private var currentPoint = Point(0, 0) private var valueAnimator: ValueAnimator? = null private var imageVIEw: ImageVIEw? = null private var layoutParams: relativeLayout.LayoutParams = relativeLayout.LayoutParams(VIEwGroup.LayoutParams.WRAP_CONTENT, VIEwGroup.LayoutParams.WRAP_CONTENT) constructor(context: Context?) : this(context, null) constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initVIEw() initPoint() setonClickListener(this) } /** * 初始化视图 */ private fun initVIEw() { imageVIEw = ImageVIEw(context) imageVIEw?.layoutParams = layoutParams imageVIEw?.visibility = VIEw.INVISIBLE imageVIEw?.setBackgroundResource(R.drawable.christmas05) addVIEw(imageVIEw) } /** * 初始化三个点 */ fun initPoint() { this.startPoint = Point(0, 0) this.endPoint = Point(dp2px(context, 200f), dp2px(context, 200f)) this.controlPoint = Point(dp2px(context, 100f), 0) } overrIDe fun onDetachedFromWindow() { super.onDetachedFromWindow() valueAnimator?.cancel() } /** * 点击开始动画 */ overrIDe fun onClick(v: VIEw?) { startAnimation() } fun dp2px(context: Context, dpVal: float): Int { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.resources.displayMetrics).toInt() }}
2、点赞效果的实现
fun startAnimation() { valueAnimator?.cancel() valueAnimator = ValueAnimator.ofObject(BezIErEvaluator(controlPoint), startPoint, endPoint).apply { addUpdateListener { currentPoint = it.animatedValue as Point imageVIEw?.x = currentPoint.x.tofloat() imageVIEw?.y = currentPoint.y.tofloat() } addListener(object : Animator.AnimatorListener { overrIDe fun onAnimationRepeat(animation: Animator?) { } overrIDe fun onAnimationEnd(animation: Animator?) { imageVIEw?.visibility = VIEw.INVISIBLE } overrIDe fun onAnimationCancel(animation: Animator?) { imageVIEw?.visibility = VIEw.INVISIBLE } overrIDe fun onAnimationStart(animation: Animator?) { imageVIEw?.visibility = VIEw.VISIBLE } }) interpolator = AccelerateInterpolator() duration = 1000 start() }}
3、贝塞尔曲线动画
它需要一个估值器,不断的计算它的运行轨迹,从起始点到终点开始计算,当中也一个支撑点进行辅助计算,这些都是由贝塞尔曲线的公式所决定的
open class BezIErEvaluator : TypeEvaluator<Point> { var controlPoint: Point constructor(controlPoint: Point) { this.controlPoint = controlPoint } overrIDe fun evaluate(t: float, startValue: Point, endValue: Point): Point { var x = (1 - t) * (1 - t) * startValue.x + 2 * t * (1 - t) * controlPoint.x + t * t * endValue.x var y = (1 - t) * (1 - t) * startValue.y + 2 * t * (1 - t) * controlPoint.y + t * t * endValue.y return Point(x.toInt(), y.toInt()) }}
在不断的计算过程中,我们就可以一直获取它的轨迹点,从而执行我们的属性动画,实现贝塞尔曲线动画
addUpdateListener { currentPoint = it.animatedValue as Point imageVIEw?.x = currentPoint.x.tofloat() imageVIEw?.y = currentPoint.y.tofloat()}
5、VIEw的使用
<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <com.example.test.customVIEw.BezIEr2Layout androID:layout_wIDth="match_parent" androID:layout_height="match_parent" /></relativeLayout>
总结 以上是内存溢出为你收集整理的Android自定义View——贝塞尔曲线实现抛物线效果全部内容,希望文章能够帮你解决Android自定义View——贝塞尔曲线实现抛物线效果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)