自定义View之小球自由落体弹跳加载控件

您所在的位置:网站首页 贝塞尔曲线的拼接 自定义View之小球自由落体弹跳加载控件

自定义View之小球自由落体弹跳加载控件

2024-01-27 15:40| 来源: 网络整理| 查看: 265

本篇文章已授权微信公众号 guolin_blog(郭霖)独家发布

效果预览

因GIF图压缩的原因动画看起来有些不流畅。 img1 应用为加载框的效果: img2

使用方法

XML:

可用的属性:

属性名称作用bounce_count小球弹跳次数ball_color小球颜色ball_count小球数量ball_radius小球半径ball_delay小球出现时间间隔(当小球数大于1时)anim_duration小球一次动画时长physic_mode开启物理效果(下落加速上升减速)random_color开启小球颜色随机random_radius开启小球大小随机(在基础大小上下浮动)random_path开启小球路径随机(在基础路径坐标上下浮动)

也可以在代码中进行配置:

bbv1 = (BounceBallView) findViewById(R.id.bbv1); bbv.config() .ballCount(15) .bounceCount(3) .ballDelay(220) .duration(3300) .radius(15) .isPhysicMode(true) .isRamdomPath(true) .isRandomColor(true) .isRandomRadius(true) .apply();

最后开启动画:

bbv1.start(); 实现思路

源码地址:https://github.com/CCY0122/bounceballview

概况

该自定义控件主要是使用了Path和属性动画来完成的,比如小球的弹跳路径,是用Path和二次贝塞尔曲线来完成的,再比如这个小球“下落加速、上弹减速”的仿物理效果是利用了Path插值器(PathInterpolator)和三次贝塞尔曲线完成的,另外诸如颜色随机、小球大小随机这些都是通过监听属性动画来实现的。接下来会讲解下这些主要的实现思路 对于自定义View的其他基本流程,如属性的获取与设置、onMeasure的重写等本文不会多讲,想了解完整流程的话可以查看源码

小球路径的实现

通过效果图可以看到,只要确定了控件大小和小球弹跳次数(bounce_count),那么就能确定小球总体的弹跳路径。因此第一个核心点就是实现小球路径的Path。假设bounce_count值被设置为3,即弹跳3次,那么路径Path的效果图应该如下图所示: 这里写图片描述 要绘制出上述这样的路径,可以利用多个二次贝塞尔曲线拼接的方式实现。关于贝塞尔曲线,若想课后系统的学习,我很推荐徐医生的这篇文章:贝塞尔曲线开发的艺术 对于二次贝塞尔曲线,这里引用一张经典图:这里写图片描述 一张图真是胜过千言万语啊~

在path中二次贝塞尔对应的方法是 path.quadTo (float x1, float y1, float x2, float y2),其中,x1/y1对应上图P1点,称做控制点,x2/y2对应P2点,就叫他终点把,P0点么就是当前path所在的起点。 由此可见,上图小球弹跳路径就是通过拼接4个二次贝塞尔曲线完成的,对于代码中对起点、终点、控制点的确定,为了方便理解,在看代码前,先附上一张图: 这里写图片描述 一张图真是胜过千言万语啊~

path的实现代码如下:

/** * 初始化球体弹跳的路径 */ private void initPath() { path.reset(); float intervalX = (viewWidth - 2 * defaultPadding) / (bounceCount + 1); //每次弹跳的间距 PointF start = new PointF();//起点位置 PointF control = new PointF(); //贝塞尔控制点 PointF end = new PointF(); //贝塞尔结束点 start.x = defaultPadding; start.y = viewHeight - defaultPaddingBottom; float controlOffsetY = viewHeight * 0.6f; //控制点向上偏移量,0.6为调试值 float deltaY = (1.2f * viewHeight + controlOffsetY) / (bounceCount + 1); //控制点高度递减值,1.2为调试值 PathMeasure tempPathMeasure = new PathMeasure(); segmentLength = new float[bounceCount + 1]; for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3