自定义button,达到一个光点绕圈运动的效果

自定义需要的方法并绑定上,用以控制自定义控件,

 


 OnMearsure 方法  用以得到自定义控件的 宽高



  去绘制控件



  获取下个坐标  继续绘制



以上是主要的 方法 , 而在 Activity中 运用的:


                                                          



以下附上  效果图   和 主要类 ,MyButton:           


      




/**
 * Created by Administrator on 2016/5/25.
 */
public class MyButton extends Button {
    //默认值
    private static final int DEFAULT_BORDER_WIDTH = 1;//dp
    private static final int DEFAULT_BORDER_COLOR = 0xFF3A9BD9;
    private static final int DEFAULT_RADIUS = 8;//dp
    private static final int DEFAULT_center_width = 20;//dp
    private static final int DEFAULT_DOT_RADIUS = 2;//dp
    private static final int DEFAULT_DOT_COLOR = 0xff0000ff;
    private static final int DEFAULT_DOT_SPEED = 2;//dp
    private static final int DEFAULT_DOT_WIDTH = 1;//dp
    private static final int DEFAULT_DOT_background = 0xff303030;
    private static final int DEFAULT_TEXT_COLOR = 0xff000000;
    private static final int DEFAULT_TEXT_SIZE = 14;//sp
    //获取的值,不设置的话就等于默认值
    private int mBorderWidth = dp2px(DEFAULT_BORDER_WIDTH);//边框的宽度
    private int mBorderColor = DEFAULT_BORDER_COLOR;//边框的颜色
    private int mRadius = dp2px(DEFAULT_RADIUS);//两端半圆形的半径
    private int mCenterWidth = dp2px(DEFAULT_center_width);//中间矩形的长度(是宽,不是高)
    private int mDotRadius = dp2px(DEFAULT_DOT_RADIUS);//小点的半径
    private int mDotColor = DEFAULT_DOT_COLOR;//小点的颜色
    private int mDotSpeed = dp2px(DEFAULT_DOT_SPEED);//小点的速度
    private int mDotWidth = dp2px(DEFAULT_DOT_WIDTH);
    private int mDotBackground = DEFAULT_DOT_background;
    private String mText;
    private int mTextColor = DEFAULT_TEXT_COLOR;
    private int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
    //画笔
    private Paint mPaint;
    //绘制左右两边半圆时要用到
    private RectF mRectFLeft;
    private RectF mRectFRight;
    //是否开始移动小点
    private boolean mStartRunning = false;
    //当前坐标xy
    private int mCurrentX;
    private int mCurrentY;
    //移动的角速度,根据速度求出来
    private float mSpeedAngle;
    //当前的角度
    private float currentAngle;
    private float mTextWidth;
    private float mTextHeight;

    public MyButton(Context context) {
        this(context, null);
    }

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
        mPaint = new Paint();
        //必须设置字体大小,不然下面获取不到字体的宽高
        mPaint.setTextSize(mTextSize);
        mTextWidth = mPaint.measureText(mText);
        mTextHeight = mPaint.descent() + mPaint.ascent();
        mCurrentX = mRadius;
        mCurrentY = 0;
        mSpeedAngle = 180 * mDotSpeed / (mRadius * 3.14f);

        mRectFLeft = new RectF(0, 0, mRadius * 2, mRadius * 2);
        mRectFRight = new RectF(mCenterWidth, 0, mCenterWidth + mRadius * 2, mRadius * 2);
    }

    private void initAttrs(AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MyButton);

        mBorderWidth = (int) typedArray.getDimension(R.styleable.MyButton_but_width, mBorderWidth);
        mBorderColor = typedArray.getColor(R.styleable.MyButton_but_color, mBorderColor);
        mRadius = (int) typedArray.getDimension(R.styleable.MyButton_radius, mRadius);
        mCenterWidth = (int) typedArray.getDimension(R.styleable.MyButton_center_width, mCenterWidth);
        mDotRadius = (int) typedArray.getDimension(R.styleable.MyButton_dot_radius, mDotRadius);
        mDotColor = typedArray.getColor(R.styleable.MyButton_dot_color, mDotColor);
        mDotSpeed = (int) typedArray.getDimension(R.styleable.MyButton_dot_speed, mDotSpeed);
        mDotWidth = (int) typedArray.getDimension(R.styleable.MyButton_dot_width, mDotWidth);
        mDotBackground = typedArray.getColor(R.styleable.MyButton_dot_background, mDotBackground);
        mText = typedArray.getString(R.styleable.MyButton_text);
        mTextColor = typedArray.getColor(R.styleable.MyButton_text_color, mTextColor);
        mTextSize = (int) typedArray.getDimension(R.styleable.MyButton_text_size, mTextSize);

        typedArray.recycle();
    }
    public void setmText(String text){
        mText = text;
        invalidate();
    }

    public void startRunning() {
        mStartRunning = true;
        invalidate();
    }

    public void stopRunning() {
        mStartRunning = false;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    //测量所需的宽度
    private int measureWidth(int widthMeasureSpec) {
        int except = mRadius * 2 + mCenterWidth + mBorderWidth + getPaddingLeft() + getPaddingRight();
        return resolveSize(except, widthMeasureSpec);
    }

    //测量所需的高度
    private int measureHeight(int heightMeasureSpec) {
        int except = mRadius * 2 + mBorderWidth + getPaddingTop() + getPaddingBottom();
        return resolveSize(except, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        canvas.translate(getPaddingLeft() + mBorderWidth / 2, getPaddingTop() + mBorderWidth / 2);

        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(mBorderColor);
        mPaint.setStrokeWidth(mBorderWidth);
        //画椭圆背景
        canvas.drawArc(mRectFLeft, 90f, 180f, false, mPaint);
        canvas.drawArc(mRectFRight, -90f, 180f, false, mPaint);
        canvas.drawLine(mRadius, 0, mRadius + mCenterWidth, 0, mPaint);
        canvas.drawLine(mRadius, mRadius * 2, mRadius + mCenterWidth, mRadius * 2, mPaint);
        //画字
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawText(mText, mRadius + mCenterWidth / 2 - mTextWidth / 2, mRadius - mTextHeight / 2, mPaint);
        //画小圆点,判断是否处于运动状态
        if (mStartRunning) {
            getNextPoint();
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(mDotBackground);
            canvas.drawCircle(mCurrentX, mCurrentY, mDotRadius, mPaint);

            mPaint.setStrokeWidth(mDotWidth);
            mPaint.setColor(mDotColor);
            mPaint.setStyle(Paint.Style.STROKE);
            canvas.drawCircle(mCurrentX, mCurrentY, mDotRadius, mPaint);
        }
        canvas.restore();
        //判断是否需要重新绘制
        if (mStartRunning) {
            invalidate();
        }
    }

    //获取下一个坐标
    private void getNextPoint() {
        if (mCurrentY == 0 && mRadius <= mCurrentX && mCurrentX < mRadius + mCenterWidth) {
            mCurrentX = Math.min(mCurrentX + mDotSpeed, mRadius + mCenterWidth);
        } else if (mCurrentY >= 0 && mCurrentY < mRadius * 2 && mCurrentX >= mRadius + mCenterWidth) {
            if (!(currentAngle > 180)) {
                mCurrentY = (int) (mRadius - mRadius * Math.sin(Math.toRadians(90 - currentAngle)));
                float f = 90 - currentAngle;
                float v = (float) (mRadius * Math.cos(Math.toRadians(f)));
                mCurrentX = (int) (mRadius + mCenterWidth + v);
                currentAngle += mSpeedAngle;
                currentAngle = Math.min(currentAngle, 180);
            } else {
                mCurrentX = mRadius + mCenterWidth;
                mCurrentY = mRadius * 2;
                currentAngle = 180;
            }
        } else if (mCurrentX <= mRadius + mCenterWidth && mCurrentX > mRadius && mCurrentY == mRadius * 2) {
            mCurrentX = Math.max(mCurrentX - mDotSpeed, mRadius);
        } else if (mCurrentY <= mRadius * 2 && mCurrentY >= 0 && mCurrentX <= mRadius) {
            if ((currentAngle < 360)) {
                mCurrentX = (int) (mRadius + mRadius * Math.cos(Math.toRadians(90 - currentAngle)));
                mCurrentY = (int) (mRadius - mRadius * Math.sin(Math.toRadians(90 - currentAngle)));
                currentAngle += mSpeedAngle;
                currentAngle = Math.min(currentAngle, 360);
            } else {
                mCurrentX = mRadius;
                mCurrentY = 0;
                currentAngle = 0;
            }
        } else {
            return;
        }
    }

    protected int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics());
    }

    protected int sp2px(int spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, getResources().getDisplayMetrics());
    }
}

 以后 还会发 关于 自定义控件的 博客 ,多多关注  。。 大家一起交流学习。     

转载请注明原创: http://blog.csdn.net/qq_34062297/article/details/51861227

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值