带进度条显示的按钮, 其效果如下所示:


其由三部分动画组成: 初始状态->圆环状态->完成状态.
0. 实现从初始到圆环的简单实现:

继承自button 类, 设置其背景
  1. public class CircleButton extends Button implements View.OnClickListener {
  2. private StateListDrawable mIdleStateDrawable;
  3. private StrokeGradientDrawable background;
  4. public CircleButton(Context context, AttributeSet attrs) {
  5. super(context, attrs);
  6. background = new StrokeGradientDrawable();
  7. // init();
  8. // setBackground(mIdleStateDrawable);
  9. setBackground(background.getGradientDrawable());
  10. setOnClickListener(this);
  11. }
  12. //.......
  13. }
其中的StrokeGradientDrawable(照搬源码) 如下:
  1. public class StrokeGradientDrawable {
  2. private int mStrokeColor; //描边颜色
  3. private int mStrokeWidth; //描边宽度
  4. public int getStrokeColor() {
  5. return mStrokeColor;
  6. }
  7. public void setStrokeColor(int strokeColor) {
  8. mStrokeColor = strokeColor;
  9. mGradientDrawable.setStroke(getStrokeWidth(), strokeColor);
  10. }
  11. public int getStrokeWidth() {
  12. return mStrokeWidth;
  13. }
  14. public void setStrokeWidth(int strokeWidth) {
  15. mStrokeWidth = strokeWidth;
  16. mGradientDrawable.setStroke(strokeWidth, getStrokeColor());
  17. }
  18. public StrokeGradientDrawable() {
  19. mGradientDrawable = new GradientDrawable();
  20. mGradientDrawable.setColor(0xff99cc00);
  21. mStrokeWidth = 5;
  22. }
  23. public GradientDrawable getGradientDrawable() {
  24. return mGradientDrawable;
  25. }
  26. public void setmGradientDrawable(GradientDrawable mGradientDrawable) {
  27. this.mGradientDrawable = mGradientDrawable;
  28. }
  29. private GradientDrawable mGradientDrawable;
  30. }
其中的GradientDrawable 为动画的关键所在
在该类中,可以设置其圆角, 填充颜色, 描边, 尺寸等. 因此,当点击按钮时,可通过动画的方式渐变到目的状态, 其实现如下(源码见MorphingAnimation 类):
  1. @Override
  2. public void onClick(View v) {
  3. final GradientDrawable gradientDrawable = background.getGradientDrawable();
  4. final int mFromWidth = getWidth();
  5. final int mToWidth = getHeight();
  6. //宽度动画
  7. ValueAnimator widthAnimation = ValueAnimator.ofInt(mFromWidth, mToWidth);
  8. widthAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  9. @Override
  10. public void onAnimationUpdate(ValueAnimator animation) {
  11. Integer value = (Integer) animation.getAnimatedValue();
  12. int leftOffset;
  13. int rightOffset;
  14. int padding;
  15. if (mFromWidth > mToWidth) {
  16. leftOffset = (mFromWidth - value) / 2;
  17. rightOffset = mFromWidth - leftOffset;
  18. } else {
  19. leftOffset = (mToWidth - value) / 2;
  20. rightOffset = mToWidth - leftOffset;
  21. }
  22. gradientDrawable.setBounds(leftOffset, 0, rightOffset, getHeight());
  23. }
  24. });
  25. //填充颜色
  26. ObjectAnimator bgColorAnimation = ObjectAnimator.ofInt(gradientDrawable, "color", 0xff99cc00, Color.WHITE);
  27. bgColorAnimation.setEvaluator(new ArgbEvaluator());
  28. //描边
  29. ObjectAnimator strokeColorAnimation =
  30. ObjectAnimator.ofInt(background, "strokeColor", 0xff99cc00, Color.GRAY);
  31. strokeColorAnimation.setEvaluator(new ArgbEvaluator());
  32. //圆角
  33. ObjectAnimator cornerAnimation =
  34. ObjectAnimator.ofFloat(gradientDrawable, "cornerRadius", 0, 30);
  35. AnimatorSet animatorSet = new AnimatorSet();
  36. animatorSet.setDuration(2000);
  37. animatorSet.playTogether(bgColorAnimation, cornerAnimation, widthAnimation,strokeColorAnimation);
  38. animatorSet.start();
  39. }
1. 源码分析(此处以Sample2Activity 为实例):
按钮的几种状态, [, IDLE, ,]


初始为IDLE 状态.
在Sample2Activity 中, 仅仅只是调用了setProgress()来实现其整个过程.其value的值从0-100不断的递增

在setProgress()方法中,其中的从初始化进入加载的圆环状态如下

 在morphToProgress() 方法,实现了从初始化到圆环状态的过度.在setListener(mProgressStateListener)中当动画完成的时候将mState 置为Progress

在createProgressMorphing() 中为创建一个MorphingAnimation实例, 其主要设置动画的圆角,宽度,颜色等等 ,在0中的简单实现也用到了这个类中的一些代码(MorphingAnimation.start() 方法中的代码片段).

在动画完成后,在setProgress 中将进行不断的界面刷新invalidate() 在调用此方法,则系统将进行重绘调用onDraw()方法


当setProgress() 到达100的时候则会调用到morphProgressToComplete() 来转换到完成的状态.

---------------------------------------------------END---------------------------------------------------------------------------------------
StateListDrawable 类, 在xml 中,通过设置<selector/> 来的background来进行按钮点击时候的背景的切换,此类则是该xml 的实现.
ColorStateList  类似.

开源项目: circular-progress-button的更多相关文章

  1. 用开源项目circular progress button实现有进度条的Button

    circular progress button可以让button实现进度条,效果和动画都做的很赞,只是有点小bug.需要注意的是按钮上的文字不能太大,否则会出现错位. 项目的地址:https://g ...

  2. Android开源项目发现---TextView,Button篇(持续更新)

    android-flowtextview 文字自动环绕其他View的Layout 项目地址:https://code.google.com/p/android-flowtextview/ 效果图:ht ...

  3. Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)

    下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...

  4. iOS及Mac开源项目和学习资料【超级全面】

    UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...

  5. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...

  6. iOS、mac开源项目及库汇总

    原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499    iOS每日一记------------之 中级完美大整理 iOS.m ...

  7. github上关于iOS的各种开源项目集合(转)

    UI 下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITable ...

  8. 分享海量 iOS 及 Mac 开源项目和学习资料

    UI 下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITable ...

  9. iOS -- 开源项目和库

    TimLiu-iOS 目录 UI 下拉刷新 模糊效果 AutoLayout 富文本 图表 表相关与Tabbar 隐藏与显示 HUD与Toast 对话框 其他UI 动画 侧滑与右滑返回手势 gif动画 ...

  10. 最全面的iOS和Mac开源项目和第三方库汇总

    标签: UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UIT ...

随机推荐

  1. java集合框架之ArrayList与LinkedList的区别

    参考http://how2j.cn/k/collection/collection-arraylist-vs-linkedlist/690.html#nowhere ArrayList和LinkedL ...

  2. 2-1赋值运算符 & 2-2自增自减运算符 &2-3

    2-1赋值运算符 先定义一个变量,把定义好的变量在赋值给另外一个变量.变向之间的互相赋值 2-2自增自减运算符 元素符,放在变量前和变量后的区别 先进行自增运算,再进行赋值运算.这里先进行num1的+ ...

  3. Linux下更改mysql版本

    想要更改linux的mysql版本,并不需要重装系统重新选择mysql版本,只需要删除掉原来的mysql然后在安装新的就可以啦 (谨记:一定要做好数据库备份) 详情请参照:大牛博客 over!over ...

  4. 767. Reorganize String

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...

  5. hdoj5493【树状数组+二分】

    题意: 给你n个人的高度, 再给出一个值代表该高度下有前面比他高的 或 后面比他高的人数, 求满足条件下的最小字典序, 不行的话输出"impossible" 思路: 对于最小字典序 ...

  6. 我不知道的C#—字符串池机制

    字符串具有值类型的特点对字符串,对同一个字符串大量修改或者对多个引用赋值同一个字符串对象时会产生大量的临时字符串对象,影响性能,但是CLR为我们做了一些工作来消除这些弊端.      对同一个字符串大 ...

  7. 01 | VIM基础攻略

    启动 vim 后,vim 处于 normal 模式. Step One: "i" -> insert 模式, ESC -> normal 模式: "x&quo ...

  8. python+smtplib 发送测试报告到邮箱

    之前有介绍过怎样快速的搭建一个python测试框架 python+unittest 搭建简易的接口测试框架 这里介绍一下,怎样使用smtplib将测试报告发送到邮箱,这样使用jenkins定时巡检,执 ...

  9. iOS UITableView 解决估算行高和指定行高的矛盾

    喜欢交朋友的加:微信号 dwjluck2013 1.一般来说 在iOS 中若UITableViewCell 固定行高, 会通过 - (CGFloat)tableView:(UITableView *) ...

  10. DRF教程2-请求和响应

    Request objects REST framework中有一个Request对象,是HttpRequest的扩展,提供了新的请求解析,Request的核心功能就是request.data,它和r ...