Android 自定义View实现动态炫酷按钮

本文介绍如何使用自定义View在Android中创建一个动态、炫酷的按钮,不依赖任何动画库,完全通过onDraw方法绘制。文章详细讲解了实现过程,包括三个关键状态:默认状态(背景变化、文字大小变化、形状缩放)、进度条状态(动态进度更新)和结束状态(恢复原状并显示Logo)。采用状态机和代理模式进行设计,提供了示例代码和Demo下载链接。
摘要由CSDN通过智能技术生成

普通按钮也就那么几种样式,看着都审美疲劳,先放效果图,演示Demo+源码在最后面



你会不会以为这个按钮是集结了很多动画的产物,我告诉你,并没有。所有的实现都是基于自定义View,采用最底层的onDraw一点一点的画出来的。没有采用一丁点的动画。虽然演示时间很短,但是要完成这么多变化,还是挺吃力。

首先讲解用法:

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final AnimationButton button = (AnimationButton) findViewById(R.id.button);
//        button.setTextSizeTouch(25);  //设置按下时字体的大小,不设置有默认值
//        button.setStrokeProgress(10); //设置进度条的厚度,不设置有默认值
//        button.setColorBase(Color.GREEN); //设置整体基色,不设置有默认值
//        button.setColorBack(Color.GRAY); //设置进度条的背景色,不设置有默认值
//        button.setStroke(3); //设置边框的厚度,不设置有默认值
//        button.setStrokeText(0); //设置文本的厚度,不设置有默认值
//        button.setTextSize(30); //设置文本的字体大小,不设置有默认值
//        button.setRound(30); //设置圆角,不设置有默认值
        button.setText("登录"); //设置文本,不设置有默认值
        button.setMode(AnimationButton.Mode.Hand_Finish); //设置进度条模式,不设置有默认值Mode.Auto_Finish
        button.setOnAnimationButtonClickListener(new AnimationButton.OnAnimationButtonClickListener() {
            @Override
            public void onClick() {
                //stopProgress方法 仅仅在button.setMode(AnimationButton.Mode.Hand_Finish);之后才有效。
                button.stopProgress();
            }
        });
    }
}
其实如果只需要最普通的功能,根本什么都不用做。因为几乎所有的参数都已经设置了固定内设置。在上面注释掉的函数用法也是用户唯一能用的几个函数,其他函数虽然标示为public,但是却是因为组件之内的方法传递,而不是给外界用户调用的。因此大家如果想自定义样式,可以调用注释里的方法。


下面开始源码讲解,首先分解功能,所有的变化可以分为三个状态:

1、默认状态,也就是最初的状态。主要完成的事情为:接收用户的点击,改变背景的样式从空心变为实心,动态改变文本的大小,然后就是逐渐得缩小成一个圆。

2、进度条状态。主要完成进度条的递进,演示图上只转了一圈。其实可以通过设置一个参数,转动多圈直到用户手动停止,甚至无限转动

3、结束状态。主要完成由圆的状态变回圆角矩形的状态,并呈现中间的Logo


既然分割出了状态,那么就采用状态机+代理模式来实现这个功能吧。首先是状态的枚举。

/**
 * Created by ccwxf on 2016/2/29.
 * 用于区别状态,有:默认状态、进度条状态、结束状态
 */
public enum Status {
    Default,
    Progress,
    Finish
}

然后是状态机的接口,也就是所有的状态需要完成的共同的事情:

/**
 * Created by ccwxf on 2016/2/29.
 */
public interface ButtonStatus {
    /**
     * @return 对应的Status值
     */
    Status getStatus();

    /**
     * 这个状态的事件处理代理
     * @param mEvent
     * @return
     */
    boolean onTouchEvent(MotionEvent mEvent);

    /**
     * 这个状态的绘制代理
     * @param mCanvas
     * @param mPaint
     */
    void onDraw(Canvas mCanvas, Paint mPaint);
}

然后我们实现按钮的代码,也就是自定义View:

/**
 * Created by ccwxf on 2016/2/29.
 */
public class AnimationButton extends View {

    private static int Color_Base = Color.rgb(24, 204, 149);
    private static int Color_Back = Color.rgb(153, 153, 153);
    private static int Stroke = 3;
    private static int Stroke_Text = 0;
    private static int Stroke_Progress = 10;
    private static int Text_Size = 30;
    private static int Text_Size_Touch = 25;
    private static int Round = 30;
    private static String Text = "提交";

    private Mode mode = Mode.Auto_Finish;
    private int maxWidth;
    private int maxHeight;
    private int colorBase = Color_Base;
    private int colorBack = Color_Back;
    private int stroke = Stroke;
    private int strokeText = Stroke_Text;
    private int strokeProgress = Stroke_Progress;
    private int textSize = Text_Size;
    private int textSizeTouch = Text_Size_Touch;
    private int round = Round;
    private String text = Text;
    //是否停止进度条,由外界设置
    private boolean isProgressStop = false;

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private ButtonStatus status;
    private OnAnimationButtonClickListener listener;

    public Mode getMode() {
        return mode;
    }

    public void setMode(Mode mode) {
        this.mode = mode;
    }

    public int getMaxWidth() {
        return maxWidth;
    }

    public int getMaxHeight() {
        return maxHeight;
    }

    public int getTextSizeTouch() {
        return textSizeTo
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值