版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、自定义view实现阻尼效果的加载动ill效果需要知识:1 .二次贝塞尔曲线2 .动画知识3 .基础自定义view知识先来解释下什么叫阻尼运动阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振 动,又称减幅振动、衰减振动。1不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小, 经过一段时间,振动就会完全停下来。 这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运动.阻尼振动系统属于耗散系统。这里的阻尼是指任何振动系统在振动中,由于外界
2、作用或系统本身固有的原因引起的振动幅度逐渐下降的特性,以及此一特性的量化表征。九,&U拓 u lu.u IN同 H.O Hk。 IH-U 和1本例中文字部分凹陷就是这种效果,当然这篇文章知识带你简单的使用跳动的水果效果实现剖析:从上面的效果图中很面就是从顶端向下掉落然后再向上那么我们首先自定义一个view继承FrameLayoutpublic class My extends FrameLayout 期间旋转即可public My(Context context) super(context);public My(Context context, AttributeSet attrs)
3、 super(context, attrs);需要素材如下三张图片:也许有人会问我看到你效果图到顶部或者底部就变成向上或者向下了答:到顶部或者底部旋转 180度即可.你三张够吗?我们现在自定义中定义几个变量/用于记录当前图片使用数组中的哪张int indexImgFlag = 0;/下沉图片前面三个图片的 idint allImgDown = R.mipmap.p2,R.mipmap.p4,R.mipmap.p6,R.mipmap.p8;/动画效果一次下沉或上弹的时间animationDuration*2= 一次完整动画时间int animationDuration = 1000;/弹起来的图
4、片ImageView iv;/ 图片下沉高度( 即从最高点到最低点的距离)int downHeight = 2;/掉下去的动画private Animation translateDown;/弹起动画private Animation translateUp;/旋转动画private ObjectAnimator rotation;我们再来看看初始化动画的方法(此方法使用了递归思想,实现无限播放动画,大家可以看看哪里不理解)/初始化弹跳动画public void MyAnmation()/下沉效果动画translateDown = new TranslateAnimation(Animatio
5、n.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,downHeight);translateDown.setDuration(animationDuration);/设置一个插值器动画将会播放越来越快模拟重力translateDown.setInterpolator(new AccelerateInterpolator();/上弹动画translateUp = new TranslateAnimation(Animation.RELA
6、TIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,downHeight,Animation.RELATIVE_TO_SELF,0);translateUp.setDuration(animationDuration);/ 设置一个插值器动画将会播放越来越慢模拟反重力translateUp.setInterpolator(new DecelerateInterpolator();/当下沉动画完成时播放启动上弹translateDown.setAnimationListener(new Animation.
7、AnimationListener() Overridepublic void onAnimationStart(Animation animation) iv.setImageResource(allImgDownindexImgFlag);rotation = ObjectAnimator.ofFloat(iv, "rotation", 180f, 360f);rotation.setDuration(1000);rotation.start();Overridepublic void onAnimationEnd(Animation animation) iv.sta
8、rtAnimation(translateUp);Overridepublic void onAnimationRepeat(Animation animation) );/当上移动画完成时播放下移动画translateUp.setAnimationListener(new Animation.AnimationListener() Overridepublic void onAnimationStart(Animation animation) indexImgFlag = 1+indexImgFlag>=allImgDown.length?0:1+indexImgFlag;iv.se
9、tImageResource(allImgDownindexImgFlag);rotation = ObjectAnimator.ofFloat(iv, "rotation", 0.0f, 180f);rotation.setDuration(1000);rotation.start();Overridepublic void onAnimationEnd(Animation animation) 递归iv.startAnimation(translateDown);Overridepublic void onAnimationRepeat(Animation animat
10、ion) );以上代码知识:插值器:会让一个动画在播放时在某一时间段加快动画或者减慢设置一个插值器动画将会播放越来越快模拟重力1. translateDown.setInterpolator(new AccelerateInterpolator();这个插值器速率表示图:.意义在于模仿下落时重力的影响最后我们初始化下图片控件到我们的自定义设置一个插值器动画将会播放越来越慢模拟反重力2. translateUp.setInterpolator(new DecelerateInterpolator(); 速率图:viewprivate void init() /初始化弹跳图片控件iv = new
11、ImageView(getContext();ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);iv.setLayoutParams(params);iv.setImageResource(allImgDown0);this.addView(iv);iv.measure(0,0);iv.getViewTreeObserver().addOnGlobalLayoutListener
12、(newViewTreeObserver.OnGlobalLayoutListener() Overridepublic void onGlobalLayout() if (!flagMeure)flagMeure =true;/由于画文字是由基准线开始path.moveTo(iv.getX()-textWidth/2+iv.getWidth()/2, textHeight+iv.getHeight()+downHeight*iv.getHeight();/计算最大弹力maxElasticFactor = (float) (textHeight / elastic);/初始化贝塞尔曲线path
13、.rQuadTo(textWidth / 2, 0, textWidth, 0);/初始化上弹和下沉动画MyAnmation();iv.startAnimation(translateDown););上面的知识:1. iv.measure(0,0);主动通知系统去测量此控件不然iv.getwidth = 0;/下面这个是同理等 iv 测量完时回调 不然 iv.getwidth = 0;2.iv.getViewTreeObserver().addOnGlobalLayoutListener(newViewTreeObserver.OnGlobalLayoutListener() 原因:TextV
14、iew tv = new TextView() 或者 LayoutInflat 填充布局都是异步所以你在new出来或者填充时直接获取自然返回0到现在为止你只需要在自定义view的onSizeChanged回调方法中调用init()即可看到动画的弹动Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) super.onSizeChanged(w, h, oldw, oldh);init(); 此方法会在onmesure方法执行完成后回调这样你就可以在此方法获得自定义 view的宽高了效果图:画文字成u形首先你
15、得知道如下知识贝塞尔曲线这里我们用到2此贝塞尔曲线我们看看大概是什么叫2次贝塞尔曲线我们看看三个点p0 p1 p2我们把p0称为开始点p1为控制点p2结束点,那么可 以用贝塞尔公式画出如图曲线这里写图片描述这里大家没必要深究怎么画出来.也不需要你懂这个要数学基础的那么我们在安卓中怎么画呢?Path path = new Path();/p0的x y坐标path.moveTo(p0.x,y);path.rQuadTo(p1.x,p1.y,p2.x,p2.y);这就是API调用方法是不是很简单 ?那么你又会问那么怎么画出来呢 很简单在 dispatchDraw方法或者onDraw中 调用Overr
16、ideprotected void dispatchDraw(Canvas canvas) super.dispatchDraw(canvas);canvas.drawPath(path,paint); 那么你画出来的效果应该和在Ps用钢笔画出来的差不多ps中钢笔工具就是二次贝塞尔曲线(借用下图片)如果你的三个点的位置如刚开的图片p0 p1 p2 (p1在p0右上方并且 p1在p2左上方)一样那么在屏幕中的显示效果如下这里随扩张下 dispatchDraw和ondraw的区别如果你的自定义 view 是继承view 那么 会先调用 ondraw->>dispatchDraw如果你的
17、自定义view 是继承viewgroup那么会跳过ondraw方法直接调用 dispathchDraw这里特别注意!!我们这个案例中继承的是FrameLayout,而frameLayout又是继承自 viewgroup 所以.那么我们回到主题如何画一个U形文字?简单就是说按照我们画出来的曲线在上面写字如:文字是" CSDN开源中国” 如何让这几个字贴着我们的曲线写出来?这里介绍一个APIcanvas.drawTextOnPath()第一个参数:文字类型为字符串第二个参数:路径也就是我们前面的二次贝塞尔曲线第三个参数:沿着路径文字开始的位置说白了偏移量第四个参数:贴着路径的高度的偏移量
18、hOffset:The distance along the path to add to the text' s starting positionvOffset:The distance above(-) or below(+) the path to position the text/ok我们看看他可以画出什么样子的文字,当然不一这种看大家对贝塞尔曲线的理解,你理解的越深那么你可以画出的图像越多 定要用贝塞尔曲线确定贝塞尔曲线的起点我们在回过头来看看我们的效果图我们可以看到文字应该是在iv(弹跳的图片中央位置且正好在iv弹到底部的位置)这里我们先补充知识在考虑计算我们来学习一下
19、文字的测量我们来看幅图De SDendET Line我们调用画文字的 API时canvas.drawTextOnPath或者canvas.drawText是从基准线开始画的也就是说途中的 baseline开始画.如:canvas.drawText( " FMY ,0,0,paint);那么你将看不到文字只能在屏幕看到文字底部如下图:iZ另一个同理 API drawTextOnPath 也是再看看几个简单的API1 . paint.measureText( " FMY ");返回在此画笔 paint下写FMY文字的宽度下面的API会把文字的距离左边left上边top
20、右边right底部的bottom的值写入此矩 形那么rect.right-rect.left=文字宽度rect.bottom-rect.top=文字高度矩形Rect rect = new Rect();将文字画入矩形目的是为了测量高度paint.getTextBounds(printText, 0, printText.length(), rect);那么请看:private void init() 初始化弹跳图片控件iv = new ImageView(getContext();ViewGroup.LayoutParams params = new ViewGroup.LayoutParam
21、s( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);iv.setLayoutParams(params);iv.setImageResource(allImgDown0);this.addView(iv);画笔的初始化 paint = new Paint();paint.setStrokeWidth(1);paint.setColor(Color.CY AN); paint.setStyle(Paint.Style.FILL);paint.setTextSize(50);paint.setAn
22、tiAlias(true);/矩形Rect rect = new Rect();/将文字画入矩形目的是为了测量高度paint.getTextBounds(printText, 0, printText.length(), rect);/文本宽度 textWidth = paint.measureText(printText);/获得文字高度 textHeight = rect.bottom - rect.top;/初始化路径path = new Path();iv.setX(getWidth()/2);iv.measure(0,0);iv.getViewTreeObserver().addOn
23、GlobalLayoutListener(newViewTreeObserver.OnGlobalLoutListener() Overridepublic void onGlobalLayout() if (!flagMeure)flagMeure =true;/由于画文字是由基准线开始path.moveTo(iv.getX()-textWidth/2+iv.getWidth()/2, textHeight+iv.getHeight()+downHeight*iv.getHeight();/计算最大弹力maxElasticFactor = (float) (textHeight / elas
24、tic);/初始化贝塞尔曲线path.rQuadTo(textWidth / 2, 0, textWidth, 0);/初始化上弹和下沉动画MyAnmation();iv.startAnimation(translateDown););我们现在写一个类当 iv 图片(弹跳图)碰到文字顶部时设置一个监听器时间正好是弹图向上到顶部的时间 期间不断让文字凹陷在恢复正常/ 用于播放文字下沉和上浮动画传入的数值必须是图片下沉和上升的一次时间public void initAnimation(int duration)/这里为什maxElasticFactor/4 好看.另一个同理这个数值大家自行调整Va
25、lueAnimator animator = ValueAnimator.ofFloat(maxElasticFactor/4, (float) (maxElasticFactor / 1.5),0);animator.setDuration(duration/2);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() Override public void onAnimationUpdate(ValueAnimator animation) calc();/ 重新画路径nowElasticFactor=
26、(float) animation.getAnimatedValue();postInvalidate(););animator.start();再来一个重新绘画路径计算的方法public void calc()/重置路径 path.reset();/由于画文字是由基准线开始path.moveTo(iv.getX()-textWidth/2+iv.getWidth()/2, textHeight+iv.getHeight()+downHeight*iv.getHeight();/画二次贝塞尔曲线path.rQuadTo(textWidth / 2, nowElasticFactor, text
27、Width, 0); 好了到这里我们看看完整源码吧package com.example.administrator.myapplication;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Pa
28、th;import android.graphics.Rect;import android.util.AttributeSet;import android.view.ViewGroup;import android.view.ViewTreeObserver;import android.view.animation.AccelerateInterpolator;import android.view.animation.Animation;import android.view.animation.DecelerateInterpolator;import android.view.an
29、imation.TranslateAnimation;import android.widget.FrameLayout;import android.widget.ImageView;public class My extends FrameLayout /画笔private Paint paint;/路径private Path path;/要输入的文本private String printText = " 正在加载 "/文本宽private float textWidth;/文本高private float textHeight;/测量文字宽高的时候使用的矩形pri
30、vate Rect rect;/最大弹力系数private float elastic = 1.5f;/最大弹力private float maxElasticFactor;/当前弹力private float nowElasticFactor;/用于记录当前图片使用数组中的哪张int indexImgFlag = 0;/下沉图片int allImgDown = R.mipmap.p2,R.mipmap.p4,R.mipmap.p6,R.mipmap.p8;/动画效果一次下沉或上弹的时间animationDuration*2= 一次完整动画时间int animationDuration = 1
31、000;/弹起来的图片ImageView iv;/图片下沉高度( 即从最高点到最低点的距离)int downHeight = 2;private Animation translateDown;private Animation translateUp;private ObjectAnimator rotation;public My(Context context) super(context);public My(Context context, AttributeSet attrs) super(context, attrs);Overrideprotected void dispatc
32、hDraw(Canvas canvas) super.dispatchDraw(canvas);canvas.drawTextOnPath(printText, path, 0, 0, paint); / 用于播放文字下沉和上浮动画传入的数值必须是图片下沉和上升的一次时间public void initAnimation(int duration)/这里为什 maxElasticFactor/4 为什么ValueAnimator animator = ValueAnimator.ofFloat(maxElasticFactor/4,(float)(maxElasticFactor / 1.5)
33、,0);animator.setDuration(duration/2);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() Overridepublic void onAnimationUpdate(ValueAnimator animation) calc();nowElasticFactor= (float) animation.getAnimatedValue();postInvalidate(););animator.start();public void calc()/重置路径path.rese
34、t();/由于画文字是由基准线开始path.moveTo(iv.getX()-textWidth/2+iv.getWidth()/2,textHeight+iv.getHeight()+downHeight*iv.getHeight();/画二次贝塞尔曲线path.rQuadTo(textWidth / 2, nowElasticFactor, textWidth, 0);/初始化弹跳动画public void MyAnmation()/下沉效果动画translateDown = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0,Anima
35、tion.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,downHeight);translateDown.setDuration(animationDuration);/ 设置一个插值器 动画将会播放越来越快模拟重力translateDown.setInterpolator(new AccelerateInterpolator();/上弹动画translateUp = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0,Animation
36、.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,downHeight,Animation.RELATIVE_TO_SELF,0);translateUp.setDuration(animationDuration);/ 设置一个插值器动画将会播放越来越慢模拟反重力translateUp.setInterpolator(new DecelerateInterpolator();/当下沉动画完成时播放启动上弹translateDown.setAnimationListener(new Animation.AnimationListener() Over
37、ridepublic void onAnimationStart(Animation animation) iv.setImageResource(allImgDownindexImgFlag);rotation = ObjectAnimator.ofFloat(iv, "rotation", 180f, 360f);rotation.setDuration(1000);rotation.start();Overridepublic void onAnimationEnd(Animation animation) iv.startAnimation(translateUp)
38、;initAnimation(animationDuration);Overridepublic void onAnimationRepeat(Animation animation) );/ 当上移动画完成时播放下移动画translateUp.setAnimationListener(new Animation.AnimationListener() Overridepublic void onAnimationStart(Animation animation) indexImgFlag1+indexImgFlag>=allImgDown.length?0:1+indexImgFlag;iv.setImageResource(allImgDownindexImgFlag);rotation = ObjectAnimator.ofFloat(iv, "rotation", 0.0f, 180f);rotation.setDuration(1000);rotation.start();Overridepublic void onAnimationEnd(Animation animation) /递归iv.startAnimation(translateDown);Overridepublic void onAnimatio
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 会计实务操作服务合同2024版规范
- 2024年光纤宽带网络建设与维护合同
- 2024年图书馆内部装修改造合同
- 2024年自卸运输车辆租赁合同样本
- 2024年商品房买卖合同(预售)
- 2024年工程设计咨询合同
- 2024年工程安装作业劳务承揽合同
- 2024年卫星导航技术服务合同标的及属性
- 海运发货合同注意事项
- 通信设备采购及安装合同
- 急性脑卒中抢救流程培训课件
- 幼儿园优质课件-中班《稻子和麦子》
- 幼儿成长档案电子通用版
- 踝关节外侧慢性不稳:修复或重建?课件
- 进展性脑卒中的诊疗策略课件
- 宝钢QBQB4202014热镀锌锌铁合金镀层钢板及钢带
- 《碳纤维片材加固混凝土结构技术规程》(2022年版)
- 某中学体育田径跑道足球场项目监理细则
- 简约表格个人简历模板-05
- 短视频:策划+拍摄+制作+运营课件(完整版)
- MSC232(82)-通过经修订的电子海图显示和信息系统(ECDIS)性能标准(中英)
评论
0/150
提交评论