版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android中如何实现抖音加载框之两颗小球转动效果
这篇文章将为大家详细讲解有关Android中如何实现抖音加载框之两颗小球转动效果,在下觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。安卓版抖音v2.5加载框:效果图如下所示:本控件效果图:使用方法源码地址:Android仿抖音加载框之两颗小球转动控件1、xml引用:
<com.douyinloadingview.DYLoadingView
android:id="@+id/dy3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000000"
app:color1="#FF00EEEE"
app:color2="#FFFF4040"
app:(其他可选属性)
/>2、java使用:
@BindView(R.id.dy1)
DYLoadingView
dy1;
@OnClick(R.id.b1)
void
start()
{
dy1.setXXXXX;
//设置属性(可选)
dy1.start();
//开始动画
}
@OnClick(R.id.b2)
void
stop()
{
dy1.stop();
//停止动画
}就酱。可用属性(rtl=righttoleft,ltr=lefttoright)部分属性说明:•color格式为32位ARGB•scaleStartFraction范围[0,0.5];scaleEndFraction范围[0.5,1]•假设ltrScale=1.3,scaleStartFraction=0.2,scaleEndFraction=0.8;那么实际效果就是一颗小球从左边开始向右移动期间,进度在0%~20%时半径逐渐从1倍放大到1.3倍,在20%~80%期间大小保持1.3倍,在80%~100%时半径逐渐从1.3倍恢复至1倍实现思路要让小球动,当然要有一个动画,通过动画来获得一个进度百分比fraction,然后小球在动画过程中的坐标、大小就可以通过这个值来计算:
private
void
initAnim()
{
fraction
=
0.0f;
stop();
anim
=
ValueAnimator.ofFloat(0.0f,
1.0f);
anim.setDuration(duration);
if
(pauseDuration
>
0)
{
anim.setStartDelay(pauseDuration);
anim.setInterpolator(new
AccelerateDecelerateInterpolator());
}
else
{
anim.setRepeatCount(ValueAnimator.INFINITE);
anim.setRepeatMode(ValueAnimator.RESTART);
anim.setInterpolator(new
LinearInterpolator());
}
anim.addUpdateListener(new
ValueAnimator.AnimatorUpdateListener()
{
@Override
public
void
onAnimationUpdate(ValueAnimator
animation)
{
fraction
=
animation.getAnimatedFraction();
invalidate();
}
});
anim.addListener(new
AnimatorListenerAdapter()
{
@Override
public
void
onAnimationStart(Animator
animation)
{
isLtr
=
!isLtr;
}
@Override
public
void
onAnimationRepeat(Animator
animation)
{
isLtr
=
!isLtr;
}
@Override
public
void
onAnimationCancel(Animator
animation)
{
isAnimCanceled
=
true;
}
@Override
public
void
onAnimationEnd(Animator
animation)
{
if
(!isAnimCanceled)
{
anim.start();
}
}
});
}代码中看到,如果小球一次移动后不需要停顿(pauseDuration=0),那么直接通过anim.setRepeatCount(ValueAnimator.INFINITE)让动画无限循环,否则的话就要通过anim.setStartDelay(pauseDuration)来设置停顿时间,然后在监听的onAnimationEnd里重启动画,以此实现每一次移动后小球能停顿一定时间。在onAnimationUpdate里,我们记录了当前动画百分比fraction,然后通过invalidate()重绘,在之后的onDraw里将通过该值画出小球。另外,每次动画开始时(或是重复时),会将isLtr取反,这个标志位的作用是标明当前哪颗球在【从左往右】移动,因为两颗球的颜色、初始半径是不一样的嘛,onDraw里画小球时是需要这个标志位协助的。有了动画进度fraction和标志位isLtr后,就可以在onDraw里画出小球了。**首先要计算小球当前的坐标**。y坐标永远是固定的,不谈,x坐标随着`fraction`的变化而变化。两颗球之间最远距离为球1半径+球2半径+两球间隔,即`distance=gap+radius1+radius2;`,这个值就是两颗球的移动范围,由此可计算出,当前【从左往右】移动的小球的x坐标和当前【从右往左】移动的小球x坐标分别为:float
ltrX
=
getMeasuredWidth()
/
2.0f
-
distance
/
2.0f;
ltrX
=
ltrX
+
(distance
*
fraction);
float
rtlX
=
getMeasuredWidth()
/
2.0f
+
distance
/
2.0f;
rtlX
=
rtlX
-
(distance
*
fraction);**接下来要计算小球当前的大小**。小球的大小也是随着动画进度变化的,上面已经说明了`scaleStartFraction`和`scaleEndFraction`属性的含义。以当前小球【从左往右】移动为例,当动画进度为0时,小球大小为初始1倍大小;当动画进度到scaleStartFraction时,小球大小将缩放到`ltrScale`倍,当动画进度为[scaleStartFraction,scaleEndFraction]范围时,小球大小保持`ltrScale`倍,当动画进度到[scaleEndFraction,1]范围时,小球则从`ltrScale`倍逐渐恢复至1倍。为了便于计算,首先将`[0,scaleStartFraction]`转换为`[0,1.0]`的真实百分比,根据`y=kx+b`(就这么个入门公式。。我都要在纸上算一遍T-T),可以得出:`floatscaleFraction=1.0f/scaleStartFraction*fraction;`,有了这个真实百分比,那么该区间里小球当前半径就好计算了:ltrBallRadius
=
ltrInitRadius
*
(1
+
(ltrScale
-
1)
*
scaleFraction);
rtlBallRadius
=
rtlInitRadius
*
(1
+
(rtlScale
-
1)
*
scaleFraction);应该好懂的吧。另外[scaleEndFraction,1]区间里小球当前半径计算思路是一样的,不谈。最后就是要画出小球。这里主要是如何画出实现两球叠加的部分的颜色。
思路1:通过xfermode方式实现:从上图可以看出用Darken、Lighten、Screen模式可以做到让叠加处上色,但是颜色不能自定义。
思路2:通过path的OP操作实现(API19):(图片摘自/customview/Path_Over)
因此,可以先构造两个小球的Path,然后再将这两个Path进行INTERSECT操作,即可获得叠加处的Path,这样就可以做到自定义叠加处的颜色了。onDraw完整代码:@Override
protected
void
onDraw(Canvas
canvas)
{
super.onDraw(canvas);
float
centerY
=
getMeasuredHeight()
/
2.0f;
float
ltrInitRadius,
rtlInitRadius;
Paint
ltrPaint,
rtlPaint;
//确定当前【从左往右】移动的是哪颗小球
if
(isLtr)
{
ltrInitRadius
=
radius1;
rtlInitRadius
=
radius2;
ltrPaint
=
paint1;
rtlPaint
=
paint2;
}
else
{
ltrInitRadius
=
radius2;
rtlInitRadius
=
radius1;
ltrPaint
=
paint2;
rtlPaint
=
paint1;
}
float
ltrX
=
getMeasuredWidth()
/
2.0f
-
distance
/
2.0f;
ltrX
=
ltrX
+
(distance
*
fraction);//当前从左往右的球的X坐标
float
rtlX
=
getMeasuredWidth()
/
2.0f
+
distance
/
2.0f;
rtlX
=
rtlX
-
(distance
*
fraction);//当前从右往左的球的X坐标
//计算小球移动过程中的大小变化
float
ltrBallRadius,
rtlBallRadius;
if
(fraction
<=
scaleStartFraction)
{
//动画进度[0,scaleStartFraction]时,球大小由1倍逐渐缩放至ltrScale/rtlScale倍
float
scaleFraction
=
1.0f
/
scaleStartFraction
*
fraction;
//百分比转换
[0,scaleStartFraction]]
->
[0,1]
ltrBallRadius
=
ltrInitRadius
*
(1
+
(ltrScale
-
1)
*
scaleFraction);
rtlBallRadius
=
rtlInitRadius
*
(1
+
(rtlScale
-
1)
*
scaleFraction);
}
else
if
(fraction
>=
scaleEndFraction)
{
//动画进度[scaleEndFraction,1],球大小由ltrScale/rtlScale倍逐渐恢复至1倍
float
scaleFraction
=
(fraction
-
1)
/
(scaleEndFraction
-
1);
//百分比转换,[scaleEndFraction,1]
->
[1,0]
ltrBallRadius
=
ltrInitRadius
*
(1
+
(ltrScale
-
1)
*
scaleFraction);
rtlBallRadius
=
rtlInitRadius
*
(1
+
(rtlScale
-
1)
*
scaleFraction);
}
else
{
//动画进度[scaleStartFraction,scaleEndFraction],球保持缩放后的大小
ltrBallRadius
=
ltrInitRadius
*
ltrScale;
rtlBallRadius
=
rtlInitRadius
*
rtlScale;
}
ltrPath.reset();
ltrPath.addCircle(ltrX,
centerY,
ltrBallRadius,
Path.Direction.CW);
rtlPath.reset();
rtlPath.addCircle(rtlX,
centerY,
rtlBallRad
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024人工挖孔桩承包合同
- 2024q长沙市商品房买卖合同
- 2024年汽车租赁合同注意事项
- 精准农业与绿色化肥管理
- 反应器工程与传质
- 2024合同模板合伙经营合同范本
- 2024商品房产购销的合同范本
- 2024个人房屋设计装修合同范本
- 2024年个人汽车的租赁合同范本
- 2024企业职工的劳动合同范本
- 直播代运营服务合作协议
- 中国特色社会主义理论体系的形成发展PPT2023版毛泽东思想和中国特色社会主义理论体系概论课件
- 电信智慧家庭工程师认证考试题库适用网大三四五级-上(单选题汇总)
- 有限空间作业安全交底清单
- 心力衰竭单病种质控查检表
- 汽车制造与试验技术
- 多元文化背景下的文艺创作
- 护理高水平专业群建设方案
- 2022年第七届青少年“学宪法讲宪法”活动知识竞赛题库(5套题)
- 浅谈中小学生国防教育的现状及其对策
- 生物传感技术
评论
0/150
提交评论