android path按钮,Android开发:带progressBar效果的Button

2015.7.30更新: 最近尝试了多种方法,终于把该lib上传到Jcenter了,使用Android studio的用户,直接在Build.Gradle中添加如下一行代码,即可以引用该库(有空的话,我会把我的方法写下来)

compile 'cn.weidongjian.android:progress-button:0.2'

这是一个带progressBar的Button,用于告诉用户正在处理数据和反馈处理结果,支付宝最新版本也有用到这个效果的按钮,请看效果图:

sx1cBGqaDPfa3okC.gif

使用方法(针对Android studio)

在项目的build.gradle中添加如下代码

dependencies { compile 'cn.weidongjian.android:progress-button:0.2' }

2 在xml中引用该控件:

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="New Button"

android:paddingLeft="30dp"

android:paddingRight="30dp"

android:textColor="@android:color/white"

android:textSize="16sp"

android:background="@drawable/selector_button"

android:id="@+id/button"

android:layout_centerVertical="true"

android:layout_centerHorizontal="true"/>

4 在activity中设置各种效果:

private ProgressButton button;

button = (ProgressButton) findViewById(R.id.button);

button.startRotate();\\添加并开始旋转progressBar

button.animError();\\显示错误符号

button.animFinish();\\显示正确符号

button.removeDrawable();\\移除progressBar

代码说明

实现方法:自定义一个drawable,然后通过textview的setCompoundDrawablesWithIntrinsicBounds的方法添加该drawable到Button中,因为Button是Extend Textview的

drawable = new ProgressDrawable(getTextSize(), this);

this.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);

自定义一个drawable,并且实现旋转,打钩,打叉的效果

public class ProgressDrawable extends Drawable {

private Paint mPaint;

private float width;

private static final int STAGE_NULL = 0, STAGE_ROTATE = 1, STAGE_FINISH = 2, STAGE_ERROR = 3;

private int stage = 0;

private RectF rectF;

private float centerX, centerY;

private float degreen = 0;

private ValueAnimator animator;

private Path pathFinish, pathErrorOne, pathErrorTwo;

private float lenFinish, lenError, length;

private int colorDefault = Color.WHITE, colorError = Color.RED;

private Button button;

private Animatable animatable;

public ProgressDrawable(float size, Button button) {

this.width = size;

this.button = button;

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setStrokeWidth(4);

rectF = new RectF(0, 0, width, width);

centerX = width/2;

centerY = width/2;

initPath();

}

private void initPath() {

pathFinish = new Path();

pathFinish.moveTo(width * 1f, width * 0.2f);

pathFinish.lineTo(width * 0.4f, width * 0.8f);

pathFinish.lineTo(0f, width * 0.4f);

PathMeasure pm = new PathMeasure(pathFinish, false);

lenFinish = pm.getLength();

pathErrorOne = new Path();

pathErrorOne.moveTo(width * 0.9f, width * 0.9f);

pathErrorOne.lineTo(width * 0.1f, width * 0.1f);

pm.setPath(pathErrorOne, false);

lenError = pm.getLength();

pathErrorTwo = new Path();

pathErrorTwo.moveTo(width * 0.9f, width * 0.1f);

pathErrorTwo.lineTo(width * 0.1f, width * 0.9f);

}

@Override

public int getIntrinsicHeight() {

return (int) width;

}

@Override

public int getIntrinsicWidth() {

return (int) width;

}

@Override

public void draw(Canvas canvas) {

if (stage == STAGE_NULL)

return;

if (stage == STAGE_ROTATE) {

canvas.save();

canvas.rotate(degreen, centerX, centerY);

canvas.drawArc(rectF, -90f, 100f, false, mPaint);

canvas.restore();

return;

}

if (stage == STAGE_FINISH) {

canvas.drawPath(pathFinish, mPaint);

mPaint.setPathEffect(null);

return;

}

if (stage == STAGE_ERROR) {

canvas.drawPath(pathErrorOne, mPaint);

canvas.drawPath(pathErrorTwo, mPaint);

mPaint.setPathEffect(null);

return;

}

}

@Override

public void setAlpha(int alpha) {

mPaint.setAlpha(alpha);

}

@Override

public void setColorFilter(ColorFilter cf) {

mPaint.setColorFilter(cf);

}

@Override

public int getOpacity() {

return PixelFormat.TRANSLUCENT;

}

public void startRotate() {

stage = STAGE_ROTATE;

mPaint.setColor(colorDefault);

button.setClickable(false);

if (animator == null) {

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

animator.setDuration(2000);

animator.setRepeatCount(ValueAnimator.INFINITE);

animator.setRepeatMode(ValueAnimator.RESTART);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

degreen += 5;

invalidateSelf();

}

});

}

animator.start();

}

public void stopRotate() {

if (animator != null && animator.isRunning()) {

animator.end();

}

}

private void setPhase(float phase) {

mPaint.setPathEffect(new DashPathEffect(new float[]{length, length}, -length * phase));

invalidateSelf();

}

public void animFinish() {

stage = STAGE_FINISH;

length = lenFinish;

mPaint.setColor(colorDefault);

startAnim();

}

public void animError() {

stage = STAGE_ERROR;

length = lenError;

mPaint.setColor(colorError);

startAnim();

}

private void startAnim() {

stopRotate();

ObjectAnimator animator = ObjectAnimator.ofFloat(this, "Phase", 1f, 0f);

animator.setDuration(400);

animator.setInterpolator(new AccelerateInterpolator());

animator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

button.setClickable(true);

if (animatable != null){

animatable.stop();

}

}

});

animator.start();

}

public void setColorDefault(int color) {

this.colorDefault = color;

}

public void setAnimatable(Animatable animatable) {

this.animatable = animatable;

}

}

其中打钩,打叉是用DashPathEffect的方法实现的,具体可以查看代码

补充说明下Canvas的Save和Restore save是保存当前的状态,比如旋转,位移等,在save后,我调用了rotate的方法旋转canvas,然后接着draw圆弧,然后调用restore的方法,就可以把canvas恢复到旋转前的状态,相当于rotate的反方向旋转是同样的效果

以上就是大概的说明,有任何疑问的,欢迎留言,源码请点击这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值