android弹球动画,Android动画之自定义Evaluator实现弹球效果
前言
今天给大家带来的是自定义Evaluator实现弹球效果,我们先给大家来个效果图。
下面我们介绍具体代码流程
1. 自定义Point类
public class Point {
private int radius;
public Point(int radius) {
this.radius = radius;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
}
2. 自定义PointEvaluator实现TypeEvaluator接口
class PointEvaluator implements TypeEvaluator{
/**
*@param fraction 动画变化中的浮点参数,0-1
*@param startValue 动画开始时的Point对象
*@param endValue 动画结束时的Point对象
*@return 动画过程中通过计算获取半径并返回一个新的Point对象
*/
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
int startRadius = startValue.getRadius();
int endRadius = endValue.getRadius();
int newRadius = (int) (startRadius + fraction * (endRadius - startRadius));
return new Point(newRadius);
}
}
3. 自定义PointView
定义弹球属性attrs
declare-styleable>
获取自定义属性,这里我们只定义了一个弹球颜色属性。
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PointView);
mColor = typedArray.getColor(R.styleable.PointView_point_color, DEFAULT_COLOR);
typedArray.recycle();
}
初始化画笔
private void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mColor);
}
重写onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
/**
* 测量view的宽高
*/
if (widthMode == MeasureSpec.AT_MOST) {
widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_WIDTH, getResources().getDisplayMetrics()) + getPaddingLeft() + getPaddingRight();
}
if (heightMode == MeasureSpec.AT_MOST) {
heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEIGHT, getResources().getDisplayMetrics()) + getPaddingTop() + getPaddingBottom();
}
/**
* 使用setMeasureDimension方法确定view的最终宽和高
*/
setMeasuredDimension(widthSize, heightSize);
}
在onSizeChanged中获取view的最终宽度和高度
这里minValue是取宽度和高度中的较小值
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
/**
* 在onSizeChanged重载方法中获取view的最终宽度和高度
*/
width = w;
height = h;
/**
* 使用width减去左右的padding
* 使用height减去上下的padding
* 并取两者中的最小值用来确定最大弹球的半径
*/
minValue = Math.min(width - getPaddingLeft() - getPaddingRight(), height - getPaddingTop() - getPaddingBottom());
}
接下来是动画的实现,使用ValueAnimator的ofObject()实现弹球动画
public void startAnimation() {
/**
* 使用ValueAnimator.ofObject()方法并使用自定义的Evaluator实现动画
*/
ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(), new Point(0), new Point(minValue * 2 / 5));
animator.setDuration(2000);
/**
* 设置插值器为BounceInterpolator,其效果为:动画结束的时候弹起
*/
animator.setInterpolator(new BounceInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
/**
* 通过getAnimatedValue获取我们变化中的Point对象
*/
mPoint = (Point) animation.getAnimatedValue();
postInvalidate();
}
});
animator.start();
}
最后是在onDraw函数中绘制弹球
@Override
protected void onDraw(Canvas canvas) {
if (mPoint != null) {
canvas.drawCircle(width / 2, height / 2, mPoint.getRadius(), mPaint);
}
}
4. xml中的引用
android:id="@+id/third_point_view"
android:layout_width="150dp"
android:layout_height="200dp"
android:layout_below="@id/second_point_view"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="@color/colorPrimary"
app:point_color="#0ff" />
5. 动画实现
在代码中获取PointView的实例然后调用startAnimation()方法实现弹球动画 MainActivity.java
public class MainActivity extends AppCompatActivity {
private PointView pointView;
private PointView secondPointView;
private PointView thirdPointView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pointView = (PointView) findViewById(R.id.point_view);
secondPointView = (PointView) findViewById(R.id.second_point_view);
thirdPointView = (PointView) findViewById(R.id.third_point_view);
findViewById(R.id.animation_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pointView.startAnimation();
secondPointView.startAnimation();
thirdPointView.startAnimation();
}
});
}
}
总结
以上就是关于今天自定义Evaluator的全部内容,不懂的童鞋可以留言或者发邮件,另外有需要源码的小伙伴可以去github下载,点击跳转到github源码地址,希望大家多多star!
android弹球动画,Android动画之自定义Evaluator实现弹球效果相关推荐
- android 直播评论动画,Android自定义View实现直播点赞特效
由于开发的需要,需要开发类似直播点赞特效的需求,于是自定义View来实现这种效果 案例图: 1.自定义View import android.animation.Animator; import an ...
- android自定义差值器,如何创建自定义插值器以在android中应用翻译动画
我想创建一个自定义插值来应用平移动画,其中动画应该通过以下函数: public static float easeIn(float t,float b , float c, float d) { re ...
- [Android]Fragment自定义动画、动画监听以及兼容性包使用
Fragment是Android在API 11之后加入的一个组件,对提高Android开发中的布局合理性和布局效率都有很大作用,尤其是在Android平板等大屏幕设备的开发中,Fragment的引入能 ...
- android view 渐变动画,Android自定义view渐变圆形动画
本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...
- android 自定义帧动画,Android 自定义方式实现帧动画效果
前言 首先说下为啥要通过自定义处理的方式去实现Android的帧动画效果,因为通过系统原生支持的xml和java代码这两种方式实现,在播放的图片量很多时,会出现内存溢出,此现象也是在做项目当中有遇到, ...
- 球体动画Android,Android自定义View实现简单炫酷的球体进度球实例代码
前言 最近一直在研究自定义view,正好项目中有一个根据下载进度来实现球体进度的需求,所以自己写了个进度球,代码非常简单.先看下效果: 效果还是非常不错的. 准备知识 要实现上面的效果我们只要掌握两个 ...
- android从一点展开动画,Android自定义View——从零开始实现可展开收起的水平菜单栏...
大家要是看到有错误的地方或者有啥好的建议,欢迎留言评论 前言:最近项目里要实现一个 可展开收起的水平菜单栏控件,刚接到需求时想着用自定义View自己来绘制,发现要实现 圆角.阴影.菜单滑动等效果非常复 ...
- android常用窗口动画,android 自定义dialog,窗口动画,
自定义dialog窗口,根据坐标可随意设置dialog显示位置,实现了窗口弹出动画 Java代码: package com.sunxu.org.IndividualityDialog; import ...
- android+清除循环动画,android自定义View之(4)-一键清除动画
android自定义View之(四)------一键清除动画 1.前言: 自己也是参考别人的一些自定义view例子,学习了一些基本的自定义view的方法.今天,我参考了一些资料,再结合自已的一些理解, ...
最新文章
- mysql model first,一个支持 CodeFirst/DbFirst/ModelFirst 的数据库小工具
- Python字典循环与字典排序
- T-SQL with as 关键字
- 操作es_ES打野皇子操作看呆Uzi:这哥们肯定是深得Lucky真传
- 网络通信 route(公司局域网配置)
- [CTO札记]Disney也进军数字出版市场了
- java 静态变量锁_线程中锁方法和静态变量的锁
- vsftpd配置权限问题
- 一个被加入下载QQ盗号木马Trojan.PSW.QQPass.rie代码的网站
- atomic 内存序_C++11的原子量与内存序浅析
- 候鸟算法在其他问题中应用时需要修改的代码
- 运用EXCEL RAND RANK INDEX函数制作抽奖器
- ubuntu 16 打开 dmg 文件
- 工业控制电气非标自动化设计安装调试PLC编程电路电气外包行业的前景预测与分析
- MySQL-7 DDL约束 标识列 TCL事务控制语言 视图view
- 基于采样的规划算法之RRT家族(三):RRT*
- Verilog轮询仲裁器设计——Round Robin Arbiter
- MTK5G-MT6853(天玑720)
- itextpdf截取pdf文件为新文件
- java自定义统计报表_用Java报表工具FineReport制作人员统计报表
热门文章
- RTMP直播应用与延时分析
- c++日志文件中文显示乱码的问题及解决办法
- 怎么在github上的私人项目中添加成员?
- 每日两SQL(9),欢迎交流~
- 大剑无锋之已知后续遍历bfegcda,中序badefcg,前序是?【面试推荐】
- 面试题:聊聊Unix与Java的IO模型?
- java基础---IO转换流
- leetcode 978. Longest Turbulent Subarray | 978. 最长湍流子数组(Java)
- 【Java语法】DateFormat时间格式转化、java.util.Date和java.sql.Date之间的相互转化
- 走进Java中的持有对象(容器类)之一 容器分类