Android UI绘制 - 动画进阶

Canvas、Layer

Android UI绘制 - 动画进阶_第1张图片

PS:addArc(Rect,startAngle,sweepAngle)中
startAngle:确定角度的起始位置
sweepAngle : 确定扫过的角度,扫过的角度360为顺时针一圈,-360为逆时针一圈,但如果扫过的角度超过360则起点会变成0度而非startAngle百分比圆的时候特别注意,这时候一般设置为359
PS:saveLayer可以为canvas创建一个新的透明图层,在新的图层上绘制,并不会直接绘制到屏幕上,而会在restore之后,绘制到上一个图层或者屏幕上(如果没有上一个图层)
PS:需要新建图层的场景(起隔离效果):
1.使用xfermode处理时,可以新建图层(隔离开不处理元素)进行xfermode处理。(直接进行处理可能会因为背景或者个别图像等原因干扰得不到预期效果)
2.个别图像具有透明度

Paint

绘制文字

方法 作用
setColor(@ColorInt int color) 设置画笔颜色
setStrokeWidth(float width) 设置画笔粗细
setTextSkewX(float f) 设置倾斜,负右斜,正为左
setARGB(int a,int r,int g,int b) 设置颜色,a为透明度
setTextSize(float textSize) 设置绘制文字大小
setFakeBoldText(boolean fakeBoldText) 是否粗体
setTextAlign(Paint.Align align) 设置文字对齐方式,LEFT,CENTER,RIGHT
setUnderlineText(boolean underlineText) 设置下划线
setStyle(Style style) 设置画笔样式,FILL,STROKE,FILL_AND_STROKE
setTypeface(Typeface typeface) 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等

绘制图像

方法 作用
setDither(boolean dither) 设置抖动处理
setAlpha(int a) 设置透明度
setAntiAlias(boolean aa) 是否开启抗锯齿
setFilterBitmap() 是否开启优化Bitmap
setColorFilter(ColorFilter filter) 设置颜色过滤
setMaskFilter(MaskFilter maskfilter) 设置滤镜的效果
setShader(Shader shader) 设置图像渐变效果
setSrokeJoin(Paint.Join join) 设置图像结合方式
setXfermode(Xfermode xfermode) 设置图像重叠效果
setPathEffect(PathEffect effect) 设置路径效果
reset() 恢复默认设置

Path

Android UI绘制 - 动画进阶_第2张图片

OP

Android UI绘制 - 动画进阶_第3张图片

setFillType 设置填充模式

Android UI绘制 - 动画进阶_第4张图片
INVERSE_EVEN_ODD(反奇偶规则)、INVERSE_WINDING(反非零环绕数规则)是EVEN_ODD(奇偶规则) 、WINDING (默认值 非零环绕数规则)的反色

PathMeasure

PathMeasure是用来测量path的。可以利用PathMeasure来截取path的某一段;获取指定长度的具体位置信息等;借此可以做出一些效果。

PS:Android知识总结——Path常用方法解析

贝塞尔曲线

// 绘制二阶贝塞尔曲线
//  (x1,y1)为控制点,(x2,y2)为终点
quadTo(float x1, float y1, float x2, float y2)
//  (x1,y1)为控制点距离起点的偏移量,(x2,y2)为终点距离起点的偏移量
rQuadTo(float x1, float y1, float x2, float y2)

// 绘制三阶贝塞尔曲线
// (x1,y1),(x2,y2)为控制点,(x3,y3)为终点
cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
// (x1,y1),(x2,y2)为控制点距离起点的偏移量,(x3,y3)为终点距离起点的偏移量
rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)

贝塞尔曲线开发的艺术
Tencent OS录音机波形动
Canvas类的最全面详解 - 自定义View应用系列

文本绘制

Paint 对于 Text 的相关设置

普通设置

paint.setStrokeWidth(5):设置画笔宽度
paint.setAntiAlias(true):设置是否使用抗锯齿功能,如果使用,会导致绘图速度变慢
paint.setStyle(Paint.Style.FILL):设置绘图样式,对于设置文字和几何图形都有效,
可取值有三种 :1、Paint.Style.FILL:填充内部 2、Paint.Style.FILL_AND_STROKE:填充内部和描边 3、Paint.Style.STROKE:仅描边
paint.setTextAlign(Align.CENTER):设置文字对齐方式
paint.setTextSize(12):设置文字大小

样式设置

paint.setFakeBoldText(true):设置是否为粗体文字
paint.setUnderlineText(true):设置下划线
paint.setTextSkewX((float) -0.25):设置字体水平倾斜度,普通斜体字是 -0.25
paint.setStrikeThruText(true):设置带有删除线效果

其他设置

paint.setTextScaleX(2):设置水平拉伸,高度不会变

Cavnas绘制

 void drawText (String text, float x, float y, Paint paint) 
 //传入的可以是 CharSequence 类型字体,所以可以实现绘制带图片的扩展文字,而且还能截取一部分绘制
void drawText (CharSequence text, int start, int end, float x, float y, Paint paint) 
 //实现截取一部分字体绘图 
void drawText (String text, int start, int end, float x, float y, Paint paint) 
 //实现截取一部分字体绘图 
void drawText (char[] text, int index, int count, float x, float y, Paint paint)
//指定各个文字位置
void drawPosText (char[] text, int index, int count, float[] pos, Paint paint) 
//指定各个文字位置
void drawPosText (String text, float[] pos, Paint paint)
//沿路径绘制
void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint) 
//沿路径绘制
void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)

基线与四线格

在这里插入图片描述

paint.setTextAlign为LEFT CENTER RIGHT的效果如下

在这里插入图片描述

四线格FontMetrics
在这里插入图片描述
FontMetrics.ascent:ascent 线的 Y 坐标 - baseline 线的 Y 坐标
FontMetrics.descent:descent 线的 Y 坐标 - baseline 线的 Y 坐标
FontMetrics.top:top 线的 Y 坐标 - baseline 线的 Y 坐标
FontMetrics.bottom:bottom 线的 Y 坐标 - baseline 线的 Y 坐标

获取字体宽高

//基线baseline默认为(0,0)
 		paint.setTextSize(100);     //单位为 sp
        String text = "搞笑我们是认真的”;
        Rect rect = new Rect();
        paint.getTextBounds(text, 0, text.length(), rect);

例子:绘制四条线

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int baselineX = 10;      //基线的 X 轴
        int baselineY = 300;    //基线的 Y 轴

        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        //获取各个线距离 baseline 线的距离
        float ascent = fontMetrics.ascent;
        float descent = fontMetrics.descent;
        float top = fontMetrics.top;
        float bottom = fontMetrics.bottom;

        //绘制文本
        canvas.drawText("搞笑我们是认真的!!!", baselineX, baselineY, paint);

        paint.setStrokeWidth(3);

        //绘制基线
        paint.setColor(Color.RED);
        canvas.drawLine(baselineX, baselineY, 1000, baselineY, paint);

        //绘制 ascent 线
        paint.setColor(Color.BLUE);
        canvas.drawLine(baselineX, baselineY + ascent, 1000, baselineY + ascent, paint);

        //绘制 descent 线
        paint.setColor(Color.BLACK);
        canvas.drawLine(baselineX, baselineY + descent, 1000, baselineY + descent, paint);

        //绘制 top 线
        paint.setColor(Color.GREEN);
        canvas.drawLine(baselineX, baselineY + top, 1000, baselineY + top, paint);

        //绘制 bottom 线
        paint.setColor(Color.YELLOW);
        canvas.drawLine(baselineX, baselineY + bottom, 1000, baselineY + bottom, paint);
    }

在这里插入图片描述

粒子效果

https://github.com/plattysoft/Leonids
广泛用于爆炸,火灾,烟雾等效果

new ParticleSystem(mActivity, 1000, R.mipmap.flower0, 10000)//上下文对象,最大粒子数目,粒子资源,粒子存留时间
                        .setSpeedModuleAndAngleRange(0.05f, 0.2f, 0, 90)//速度最小值,速度最大值,发射角度最小值,发射角度最大值
                        .setRotationSpeed(60)//粒子元素自身旋转速度
                        //施加一个力
                        .setAcceleration(0.00005f, 90)// 力的加速度,力的方向
                        //发射一次 
                        //.oneShot(mBtn1,200)//发射位置,发射数量
                        //发射多次
                        .emit(0, -100, 30, 10000);//发射位置X,发射位置Y,发射粒子数,持续发射时间

动画辅助

插值器、估值器

插值器的本质:根据动画的进度(0%-100%)计算出当前属性值改变的百分比

android内置9种插值器

作用 资源ID 对应的Java类
动画加速进行 @android:anim/accelerate_interpolator AccelerateInterpolator
快速完成动画,超出再回到结束样式 @android:anim/overshoot_interpolator OvershootInterpolator
先加速再减速 @android:anim/accelerate_decelerate_interpolator AccelerateDecelerateInterpolator
先退后再加速前进 @android:anim/anticipate_interpolator AnticipateInterpolator
先退后再加速前进,超出终点后再回终点 @android:anim/anticipate_overshoot_interpolator AnticipateOvershootInterpolator
最后阶段弹球效果 @android:anim/bounce_interpolator BounceInterpolator
周期运动 @android:anim/cycle_interpolator CycleInterpolator
减速 @android:anim/decelerate_interpolator DecelerateInterpolator
匀速 @android:anim/linear_interpolator LinearInterpolator

估值器的定义:根据当前属性改变的百分比来计算改变后的属性值
android内置3种估值器
IntEvaluator:整型属性
FloatEvaluator:浮点型属性
ArgbEvaluator:Color属性

PS:如上三种属性估值器,我们可以根据需求定义出自身所需的各种估值器(比如点PointEvaluator,透明度AlphaEvaluator等)

PS:属性动画的运行(插值器和估值器的协同工作):它们是实现非匀速动画的重要手段。属性动画是对属性做动画,属性要实现动画,首先由TimeInterpolator(插值器)根据时间流逝的百分比计算出当前属性值改变的百分比,并且插值器将这个百分比返回,这个时候插值器的工作就完成了。比如插值器返回的值是0.5,很显然我们要的不是0.5,而是当前属性的值,即当前属性变成了什么值,这就需要估值器根据当前属性改变的百分比来计算改变后的属性值,根据这个属性值,我们就可以设置当前属性的值了

Scroller

Android View体系(四)从源码解析Scroller

VelocityTracker

//获取一个VelocityTracker 实例
VelocityTracker mVelocityTracker = VelocityTracker.obtain();
//将要跟踪的MotionEvent加入
mVelocityTracker.addMovement(event);
//想要确定速度的时候调用
//units 代表速度单位;1000:每毫秒运动1000个像素
mVelocityTracker.computeCurrentVelocity(int units)
//获取X Y方向的速度
mVelocityTracker.getXVelocity()
mVelocityTracker.getYVelocity()
//回收资源
mVelocityTracker.recycle();

GestureDetector手势识别

OnGestureListener,这个Listener监听一些手势,如单击、滑动、长按等操作:

  • onDown(MotionEvent e):用户按下屏幕的时候的回调。
  • onShowPress(MotionEvent e):用户按下按键后100ms(根据Android7.0源码)还没有松开或者移动就会回调,官方在源码的解释是说一般用于告诉用户已经识别按下事件的回调(我暂时想不出有什么用途,因为这个回调触发之后还会触发其他的,不像长按)。
  • onLongPress(MotionEvent e):用户长按后(好像不同手机的时间不同,源码里默认是100ms+500ms)触发,触发之后不会触发其他回调,直至松开(UP事件)。
  • onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):手指滑动的时候执行的回调(接收到MOVE事件,且位移大于一定距离),e1,e2分别是之前DOWN事件和当前的MOVE事件,distanceX和distanceY就是当前MOVE事件和上一个MOVE事件的位移量。
  • onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY):用户执行抛操作之后的回调,MOVE事件之后手松开(UP事件)那一瞬间的x或者y方向速度,如果达到一定数值(源码默认是每秒50px),就是抛操作(也就是快速滑动的时候松手会有这个回调,因此基本上有onFling必然有onScroll)。
  • onSingleTapUp(MotionEvent e):用户手指松开(UP事件)的时候如果没有执行onScroll()和onLongPress()这两个回调的话,就会回调这个,说明这是一个点击抬起事件,但是不能区分是否双击事件的抬起。

OnDoubleTapListener,这个Listener监听双击和单击事件。

  • onSingleTapConfirmed(MotionEvent e):可以确认(通过单击DOWN后300ms没有下一个DOWN事件确认)这不是一个双击事件,而是一个单击事件的时候会回调。
  • onDoubleTap(MotionEvent e):可以确认这是一个双击事件的时候回调。
  • onDoubleTapEvent(MotionEvent e):onDoubleTap()回调之后的输入事件(DOWN、MOVE、UP)都会回调这个方法(这个方法可以实现一些双击后的控制,如让View双击后变得可拖动等)。

OnContextClickListener 鼠标右键

  • onContextClick(MotionEvent e):当鼠标/触摸板,右键点击时候的回调。

SimpleOnGestureListener,实现了上面三个接口所有方法,空实现。

ViewConfiguration

//双击间隔时间不大于该时间,则判定为双击事件
getDoubleTapTimeout()
//连续重复按键的延迟毫秒时间
getKeyRepeatDelay() 
//重复按键的超时毫秒时间
getKeyRepeatTimeout()
//长按超时毫秒时间。超出则表示长按
getLongPressTimeout()
//在(子)组件上按住状态的持续毫秒时间
getPressedStateDuration() 
//两次touch间的像素距离值。若满足它,在符合超时规则的同时,可被视为一个双击操作
getScaledDoubleTapSlop() 
//当用户touch在屏幕边缘时,插入一定像素值,以寻找出可触摸内容
getScaledEdgeSlop() 
//边缘渐变的像素长度
getScaledFadingEdgeLength() 
//View的最大绘图缓存,以字节表示
getScaledMaximumDrawingCacheSize() 
//返回一个表示飞速滑动的最大初始速率值。单位是 像素/秒
getScaledMaximumFlingVelocity() 
//返回一个表示飞速滑动的最小初始速率值。单位是 像素/秒
getScaledMinimumFlingVelocity() 
//飞速滑动,当要显示view的边缘效果时,view可以超出的最大像素距离值
getScaledOverflingDistance() 
//滚动后,当要显示view的边缘效果时,view可以超出的最大像素距离值
getScaledOverscrollDistance() 
//一个touch动作,满足该像素距离时,可以认为用户滚动了一整个页面
getScaledPagingTouchSlop() 
//获取水平滚动条的宽 或 垂直滚动条的高,以像素为单位
getScaledScrollBarSize() 
//满足这个像素距离,可以认为用户在滚动中
getScaledTouchSlop() 
//定义一个window范围外的像素距离值,当touch动作,满足在该值以外,则认为可以dismiss该window
getScaledWindowTouchSlop() 
//scrollBar逐渐消失的毫秒值
getScrollBarFadeDuration() 
//在滚动条消失前的延迟时间
getScrollDefaultDelay() 
//一个代表了摩擦系数的标量。它应用在flings 或 scrolls 状态。
getScrollFriction() 
//点击超时毫秒值。当用户在该间隔时间内,没有”move”操作,就认为是单击操作;反之认为是scroll操作
getTapTimeout() 
//为了响应用户对焦动作,焦点框显示的超时毫秒值。应该是用在摄像头一类的操作里。
getZoomControlsTimeout() 
//是否有永久的 菜单键
hasPermanentMenuKey() 

回弹

回弹动画只需要在属性动画中加入BounceInterpolator插值器即可

TranslateAnimation anim = new TranslateAnimation(-100, 0, 0, 0);
anim.setInterpolator(new BounceInterpolator());
anim.setDuration(1000);

惯性滑动

Scroller.fling()

拖拽

https://blog.csdn.net/xiatiandefeiyu/article/details/78325836

材料

Airbnb的lottie-android
http://www.cnblogs.com/ldq2016/p/5217590.html
https://blog.csdn.net/csdn2497242041/article/details/79250688
https://blog.csdn.net/huangxiaoguo1/article/details/79032186

你可能感兴趣的:(Android基础)