开源项目: circular-progress-button
2024-08-27 10:49:38
带进度条显示的按钮, 其效果如下所示:
其由三部分动画组成: 初始状态->圆环状态->完成状态.
0. 实现从初始到圆环的简单实现:
继承自button 类, 设置其背景
public class CircleButton extends Button implements View.OnClickListener {
private StateListDrawable mIdleStateDrawable;
private StrokeGradientDrawable background;
public CircleButton(Context context, AttributeSet attrs) {
super(context, attrs);
background = new StrokeGradientDrawable();
// init();
// setBackground(mIdleStateDrawable);
setBackground(background.getGradientDrawable());
setOnClickListener(this);
}
//.......
}
其中的StrokeGradientDrawable(照搬源码) 如下:
public class StrokeGradientDrawable {
private int mStrokeColor; //描边颜色
private int mStrokeWidth; //描边宽度
public int getStrokeColor() {
return mStrokeColor;
}
public void setStrokeColor(int strokeColor) {
mStrokeColor = strokeColor;
mGradientDrawable.setStroke(getStrokeWidth(), strokeColor);
}
public int getStrokeWidth() {
return mStrokeWidth;
}
public void setStrokeWidth(int strokeWidth) {
mStrokeWidth = strokeWidth;
mGradientDrawable.setStroke(strokeWidth, getStrokeColor());
}
public StrokeGradientDrawable() {
mGradientDrawable = new GradientDrawable();
mGradientDrawable.setColor(0xff99cc00);
mStrokeWidth = 5;
}
public GradientDrawable getGradientDrawable() {
return mGradientDrawable;
}
public void setmGradientDrawable(GradientDrawable mGradientDrawable) {
this.mGradientDrawable = mGradientDrawable;
}
private GradientDrawable mGradientDrawable;
}
其中的GradientDrawable 为动画的关键所在
在该类中,可以设置其圆角, 填充颜色, 描边, 尺寸等. 因此,当点击按钮时,可通过动画的方式渐变到目的状态, 其实现如下(源码见MorphingAnimation 类):
@Override
public void onClick(View v) {
final GradientDrawable gradientDrawable = background.getGradientDrawable();
final int mFromWidth = getWidth();
final int mToWidth = getHeight();
//宽度动画
ValueAnimator widthAnimation = ValueAnimator.ofInt(mFromWidth, mToWidth);
widthAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
int leftOffset;
int rightOffset;
int padding;
if (mFromWidth > mToWidth) {
leftOffset = (mFromWidth - value) / 2;
rightOffset = mFromWidth - leftOffset;
} else {
leftOffset = (mToWidth - value) / 2;
rightOffset = mToWidth - leftOffset;
}
gradientDrawable.setBounds(leftOffset, 0, rightOffset, getHeight());
}
});
//填充颜色
ObjectAnimator bgColorAnimation = ObjectAnimator.ofInt(gradientDrawable, "color", 0xff99cc00, Color.WHITE);
bgColorAnimation.setEvaluator(new ArgbEvaluator());
//描边
ObjectAnimator strokeColorAnimation =
ObjectAnimator.ofInt(background, "strokeColor", 0xff99cc00, Color.GRAY);
strokeColorAnimation.setEvaluator(new ArgbEvaluator());
//圆角
ObjectAnimator cornerAnimation =
ObjectAnimator.ofFloat(gradientDrawable, "cornerRadius", 0, 30);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(2000);
animatorSet.playTogether(bgColorAnimation, cornerAnimation, widthAnimation,strokeColorAnimation);
animatorSet.start();
}
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 类似.
最新文章
- android接入微信分享(朋友、朋友圈)、QQ分享(好友、空间)
- eclipse中jsp文档无语法着色,安装Eclipse Java Web Developer Tools插件
- windows下远程桌面连接centos
- Zookeeper总结
- nginx 负载均衡集群解决方案 healthcheck_nginx_upstreams (一)
- 分布式一致性原理—CAP
- PythonChallenge 2:爬虫和正则表达式
- monkey与monkeyrunner的使用
- INI解析模块的C++实现
- 树莓派连接GPS模块
- Windows10 Ubuntu bash 配置 LAMP+JDK+Tomcat
- 本部jdk切换的坑!!!
- HTTP之状态码
- salesforce lightning零基础学习(八) Aura Js 浅谈一: Component篇
- Win10上运行Docker
- 在头文件中声明class 类 与 include类所在的头文件区别---理解
- C++STL简介
- 大牛是怎么思考设计MySQL优化方案的?
- Java入门系列-06-运算符
- intellij IEDA 从svn拉环境到正常运行