设为首页 加入收藏

TOP

在Android上仿百度贴吧客户端Loading图标小球(三)
2017-10-13 10:37:06 】 浏览:9407
Tags:Android 百度贴吧 客户端 Loading 图标 小球
metrics.top, 500, metrics.top, paint);
  • // bottom
  • paint.setColor(Color.GREEN);
  • canvas.drawLine(0, metrics.bottom, 500, metrics.bottom, paint);
  •   首先是在画布的(600,200)处画上文字,为了方便观察(600,200)在文字的什么部位,我在(600,200)处画了一个半径3像素的圆圈。然后平移画布到(600,200)的地方然后依次画出了文字的边框图以及FontMetrics信息里的top、ascent、descent、bottom信息

      我把运行结果截图做了处理,方便大家看

     

    文字的各个边界

      从结果看(600,200)那个蓝色的点并不是在文字的左上角,而是左下角,这个点所在的y坐标即是大家常说的BaseLine的位置,那现在这个函数Canvas.drawText( String text, float x, float y, Paint paint)就可以理解为——将文字的基准点放在(x,y)处,那么这个基准点可以改变吗?答案是肯定的,可以通过绘制文字的画笔的setTextAlign(Align align)方法设置为Paint.Align.CENTER或者Paint.Align.RIGHT,如果不设置的话默认是Paint.Align.LEFT。读者朋友们有兴趣的话可以试试设置成CENTER之后(600,200)的蓝圈圈是不是跑到了文字的中部呢?从上图我们也可以看出,整个文字是介于FontMetrics.top和FontMetrics.bottom之间。

      好了,贴上文字居中的代码,相信认真看上边那段话的朋友一定能轻松读懂

    1. private void drawCenterText(Canvas canvas, Paint textPaint, String text) {
    2. Rect rect = new Rect(0, 0, mWidth, mHeight);
    3. textPaint.setTextAlign(Paint.Align.CENTER);
    4. Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
    5. //文字框最高点距离baseline的距离(负数)
    6. float top = fontMetrics.top;
    7. //文字框最低点距离baseline的距离(正数)
    8. float bottom = fontMetrics.bottom;
    9. int centerY = (int) (rect.centerY() - top / 2 - bottom / 2);
    10. canvas.drawText(text, rect.centerX(), centerY, textPaint);
    11. }

      分析好上边的代码 我们就能绘制出一个静态的小球了,动画既然要动,肯定就像汽车一样需要一个"引擎",在上面说到的绘制波浪路径的函数中我们忽略了getActionPath(float percent)的参数percent,这个参数即是当前动画的进度,那么我们如何来制造这个进度呢?需要怎样把这个动画“引擎”点燃呢。我们可以通过各种手段计时,生成一个计时Thread或者自己写一个Handler等等,只要能均匀的生成进度即可。

      本文中用到一个巧妙的定时器ValueAnimator 大家常说的属性动画ObjectAnimator就是它的一个子类,使用它来作为动画的引擎再方便不过了,从字面翻译"ValueAnimator"那就是“值动画者”直译虽然low但是恰恰更好理解,就是让数值动起来,从什么值动到什么值呢?

    1. ValueAnimator animator = ValueAnimator.ofFloat(0, 1);

      这句话就是定义一个值从0变化到1的一个animator,我们的percent值就是从0变化到1的中间过程值,那么怎么得到这个过程值呢?——监听器!对!

    1. animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    2. @Override
    3. public void onAnimationUpdate(ValueAnimator animation) {
    4. float percent = animation.getAnimatedFraction();
    5. }
    6. });

      那么数值从0变到1需要多久呢?怎么能无限重复呢?重复的时候是重头开始还是反转进行呢?别急下面三句话就是让动画无限重复,每次从头开始,一个周期1000毫秒

    1. animator.setDuration(1000);
    2. animator.setRepeatCount(ValueAnimator.INFINITE);
    3. animator.setRepeatMode(ValueAnimator.RESTART);

      好了,引擎设置好了,发动

      animator.start();

      上效果

     

    鬼畜版

      WTF!这是什么鬼,为什么鬼畜地慢几拍?

      打印出来横坐标看看

    1. 07-09 18:18:47.308 E/Jcs: getActionPath: -21
    2. 07-09 18:18:47.326 E/Jcs: getActionPath: -15
    3. 07-09 18:18:47.342 E/Jcs: getActionPath: -10
    4. 07-09 18:18:47.359 E/Jcs: getActionPath: -5
    5. 07-09 18:18:47.375 E/Jcs: getActionPath: -2
    6. 07-09 18:18:47.392 E/Jcs: getActionPath: 0
    7. 07-09 18:18:47.409 E/Jcs: getActionPath: 0

      最后几拍的数值差好像不太对呀!拍拍脑门突然一想,我的动画不均匀是忘记设置一个均匀的插值器了!哎!

    1. animator.setInterpolator(new LinearInterpolator());

      补上一个线性插值器,整个世界都顺畅了

     

      百度Loading小球Github源码

      三、结语

      第一次写文章,不免有些疏漏之处,望多多指教!后续我会不定期更新新的内容,争取把写文章当成自己生活的一部分。

      后记(2017年7月27日15:02:39)

      有不少读者问到关于小球和边缘锯齿的问题,我分别用如下方式实现loading小球

      1、Canvas的clip方式限制波浪边界(本文提到的方法)

      2、使用Xfermode方式限制波浪和圆形的边界

      3、用Xfermode方式限制白色文字,用shader方式限制圆形的边界

      下边是效果预览图,代码已经提交到github上了,讲解部分尽快补到此文中

    三种方式对比

     

    首页 上一页 1 2 3 下一页 尾页 3/3/3
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇Android集成FFmpeg 下一篇FFmpeg编译Android版本

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目