更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680
本篇文章将从Android 自定义属性动画&Camera动画来介绍自定义View:

1.相关知识点

对于Androi的帧动画,可以制作gif图片,有时为了能够动态的生成帧动画,就得需要使用代码构建了

AnimationDrawable类中使用 addFrame用来添加帧。

AnimationDrawable类中使用 start来启动动画。

AnimationDrawable类中使用 stop来停止动画。

  1. 当移动位置不是相对于ParentView或者Window时,补间动画只实现了View图像位置的改变,但控件并没有发生位移

    说明:当属性动画移动后,如果不会到原来的位置,那么点击新的位置,将接受不到Click事件,点击原来的位置可以接收到点击事件

  2. 补间动画通过不断的调用OnDraw方法来进行UI的绘制,而属性动画一般只调用ViewGroup进行绘制

  3. 属性动画不会主动恢复到原来的状态,而是一直保持新的状态,直到下一次改变

  4. 属性动画可以使用playToggther,play..with,play...[width]... after,playSequentaily进行动画的控制,使用起来非常方便

  5. 属性动画可以通过ObjectAnimator和PropertyValueHolder进行动态控制,增加了动画的灵活性

2.pivot:X和piovtY中心点

[图片上传失败...(image-20acc2-1573022389835)]

中心点对所有动画属性都起作用,scale(参见QQ侧滑),translate,rotate

中心点描述了动画的发展方向

另外对于补间动画的理解中容易出现错误的地方,更正如下:

RotateAnimation ra = new RotateAnimation(fromDegrees, toDegrees, pivotX, pivotY)

pivotX,pivotY当数值大于1时表示的是实际像素

RotateAnimation ra = new RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue)

pivotX,pivotY当数值大于1时表示的是比例位置

3.Animation自定义动画

3.1继承Animation自定义动画

public class CustomAnimation extends Animation {

    @Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
t.getMatrix().setTranslate((float) (Math.sin(10*interpolatedTime)*50), 0);
} }

3.2使用ValueAnimator结合监听器自定义动画

            final ShapeHolder ball5 = balls.get(4);
ValueAnimator valueAnimator5 = ValueAnimator.ofFloat(0f,
getHeight() - ball5.getHeight());
valueAnimator5.setDuration(500);
valueAnimator5.addUpdateListener(new AnimatorUpdateListener() {
// ValueAnimator需要自己在监听处理中设置对象参数
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 用animation.getAnimatedValue()得到当前的属性值,设置进动画对象中
ball5.setY((Float) animation.getAnimatedValue());
// 记得要刷新View否则不会调用重新绘制
invalidate();
}
});

3.3使用TypeEvaluator自定义动画

public class Point {

    private float x;

    private float y;

    public Point(float x, float y) {
this.x = x;
this.y = y;
} public void setX(float x){
this.x = x
}
public void setY(float y){
this.y = y;
} public float getX() {
return x;
} public float getY() {
return y;
} }

public class PointEvaluator implements TypeEvaluator{

    @Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
Point startPoint = (Point) startValue;
Point endPoint = (Point) endValue;
float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());
Point point = new Point(x, y);
return point;
} }

public class MyTaget{
private Point point = new Point(0f,0f);
public void setPoint(Point p){
this.point = point;
}
public Point getPoint(){
return this.point;
}
} Point point1 = new Point(0, 0);
Point point2 = new Point(300, 300);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), point1, point2);
anim.setTarget(new MyTarget());
anim.setDuration(5000);
anim.start();

或如下使用

ObjectAnimator.ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values)

4.通关过扩展原有属性方式自定义动画

(由于属性动画的属性必须具有setter与getter,对于一些特别的属性,需要使用代理)

public class WrapperView{
private View targetView;
public WrapperView(View targetView){
this.targetView = targetView;
}
public void setWidth(int width){
targetView.getLayoutParams().width = width;
targetView.requestLayout();
}
public int getWidth(){
return targetView.getLayoutParams().width;
}
}

使用方法

WrapperView wrapper = new WrapperView(mLinearLayout);
ObjectAnimator.ofInt(wrapper,"width",300).setDuration(3000).start();

Android 自定义动画Animation 使用Camera实现3D动画效果,这里的Camera不是相机,而是场景动画,意味着有导演

public class MyAnimation extends Animation {
int mCenterX,mCenterY; Camera camera = new Camera(); public MyAnimation() {
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
camera.save();
camera.translate(0f, 0f, (1300 - 1300*interpolatedTime));
camera.rotateY(360*interpolatedTime);
camera.getMatrix(matrix);
matrix.preTranslate(-mCenterX, -mCenterY);
matrix.postTranslate(mCenterX,mCenterY);
camera.restore();
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
//初始化中间坐标
mCenterX = width/2;
mCenterY = height/2; setDuration(2000);
setFillAfter(true);
setInterpolator(new LinearInterpolator());
}
}

更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680
原文链接https://www.cnblogs.com/xgjblog/p/6283757.html

高级UI晋升之自定义View实战(六)的更多相关文章

  1. 高级UI晋升之自定义View实战(九)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 1.前言: 本文采用自定义view的方法来实现一键清除的动画这个功能. 2.效果 ...

  2. 高级UI晋升之自定义View实战(五)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从自定义View利器Canvas和Paint来进行详解 一.Canvas ...

  3. 高级UI晋升之自定义view实战(七)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义ViewGroup实现瀑布流效果来进行详解dispatchTouch ...

  4. 高级UI晋升之自定义View实战(八)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义流式布局来进行介绍: 一般常见的流式布局由两种,一种是横向的个数固定 ...

  5. 高级UI晋升之常用View(三)中篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从ViewPager来介绍常用View:文章目录 一.简介 二.基本使用 ...

  6. 高级UI晋升之常用View(三)上篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将先从以下两个内容来介绍常用View: [RecycleView] [Ca ...

  7. 高级UI晋升之常用View(三)下篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从WebView来介绍常用View: 一.WebView介绍 Andro ...

  8. 高级UI晋升之View渲染机制(二)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...

  9. Android自定义View实战(SlideTab-可滑动的选择器)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/52178553 本文出自:[openXu的博客] 目录: 初步分析重写onDraw绘制 重写o ...

随机推荐

  1. [ERR] 1114 - The table 'xxx' is full

    异常原因: 磁盘空间不足 解决办法: 1. 新增磁盘 2. 删除无用数据 信息补充: df: df -h #查询磁盘空间命令 du: du|sort -nr|more #显示目录或者文件所占空间 du ...

  2. luoguP1313 计算系数 题解(NOIP2011)

    P1313 计算系数 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<cm ...

  3. 基于QRcode的带有文字+图片的二维码的Vue组件

    1 <template> 2 <!-- 生成二维码开放接口: 3 二维码内容[通常为url] 4 二维码大小[限制为正方形] 二维码下方显示:文字 5 二维码中间显示:图片--> ...

  4. PascalCase & camelCase & kebabCase

    帕斯卡拼写法( 也叫大骆驼拼写法),一种计算机编程中的变量命名方法.它主要的特点是将描述变量作用所有单词的首字母大写,然后直接连接起来,单词之间没有连接符.比如: Age LastName Winte ...

  5. 2018-8-10-wpf-绑定-DataGridTextColumn-

    title author date CreateTime categories wpf 绑定 DataGridTextColumn lindexi 2018-08-10 19:16:53 +0800 ...

  6. 服务器修改静态ip

    ifconfig,看当前网卡名字 设置 ip地址,子网掩码 ,广播地址 ifconfig eth1 172.16.11.25 netmask 255.255.255.0 broadcast 172.1 ...

  7. opengl 库glew

    OpenGL OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库.OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL.IRIS GL是一个工业标准的3D图形软件 ...

  8. 选择恐惧症的福音!教你认清MVC,MVP和MVVM(转:示例挺好,不太赞同画图)

    转自:http://zjutkz.net/2016/04/13/%E9%80%89%E6%8B%A9%E6%81%90%E6%83%A7%E7%97%87%E7%9A%84%E7%A6%8F%E9%9 ...

  9. Qt QSS图片样式切割,三种状态normal,hover,pressed

    要切割的样式图片如下: pix_Button->setStyleSheet("QPushButton{ border-image:url(:/image/MyButtonimage/m ...

  10. RAM/ROM IP一次性总结

    1, 若需要修改memory mode, 需重新编译; 若不需要修改memory mode, 直接修改宏参数即可; 2, 宏参数列表: 3, 注意用LE搭memory的情况; 4, memory ty ...