android自定义渐变色圆环,精通Android自定义View(十九)自定义圆形炫彩加载转圈效果...

1 效果

4e2d24a47ff825042b5db9a8666aa26a.gif

2 源码

public class JiondongView extends View {

private Paint mBackgroundPaint;

private float mScaledDensity;

//背景的宽与高

private int mBgWidth;

private int mBgHeight;

//屏幕的宽与高

private int mMeasureWidth=0;

private int mMeasureHeight=0;

//圆角

private int mBgRx;

private int mBgRy;

private RectF mBgRectF;

//误差

private int flag;

private Paint mTextdPaint;

private String mMsgText="!";

private float mMsgTextLength;

private float mMsgTextHeight;

private Paint mCirclPaint;

private Paint mCirclRingPaint;

//默认view的宽度

private int mDefaultWidth = dp2px(100);

private int mDefaultHeight =mDefaultWidth;

private float mCirclRingRoateAle=0;

private ValueAnimator mValueAnimator;

public JiondongView(Context context) {

super(context);

init(context,null,0);

}

public JiondongView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

init(context,attrs,0);

}

public JiondongView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context,attrs,defStyleAttr);

}

private void init(Context context, @Nullable AttributeSet attrs, int defStyleAttr){

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

mValueAnimator.setDuration(380);

mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator valueAnimator) {

mCirclRingRoateAle=360*((Float)valueAnimator.getAnimatedValue());

Log.e("loadingviw","loading");

invalidate();

}

});

mValueAnimator.setRepeatCount(10000);

mValueAnimator.setRepeatMode(ValueAnimator.RESTART);

mValueAnimator.setInterpolator(new LinearInterpolator());

//屏幕密度缩放比例

mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;

//背景

mBackgroundPaint = new Paint();

mBackgroundPaint.setAntiAlias(true);

mBackgroundPaint.setDither(true);

mBackgroundPaint.setStyle(Paint.Style.FILL);

mBackgroundPaint.setColor(Color.parseColor("#bb2A2A2A"));

//圆

mCirclPaint = new Paint();

mCirclPaint.setAntiAlias(true);

mCirclPaint.setDither(true);

mCirclPaint.setStyle(Paint.Style.FILL);

mCirclPaint.setColor(Color.parseColor("#ffffff"));

//环

mCirclRingPaint = new Paint();

mCirclRingPaint.setAntiAlias(true);

mCirclRingPaint.setDither(true);

mCirclRingPaint.setStyle(Paint.Style.STROKE);

mCirclRingPaint.setStrokeWidth(2.6f*mScaledDensity);

mCirclRingPaint.setColor(Color.parseColor("#ffcc00"));

mBgWidth = (int) (60*mScaledDensity);

mBgHeight = (int) (60*mScaledDensity);

mBgRx= (int) (8*mScaledDensity);

mBgRy= (int) (8*mScaledDensity);

flag= (int) (16*mScaledDensity);

mTextdPaint = new Paint();

mTextdPaint.setAntiAlias(true);

mTextdPaint.setDither(true);

mTextdPaint.setTextSize(20*mScaledDensity);

mTextdPaint.setStyle(Paint.Style.STROKE);

mTextdPaint.setColor(Color.parseColor("#000000"));

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//测量计算宽度

int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);

int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);

if (widthSpecMode == MeasureSpec.EXACTLY) {

//当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小

mMeasureWidth = widthSpecSize;

} else {

//指定默认大小

mMeasureWidth = mDefaultWidth;

if (widthSpecMode == MeasureSpec.AT_MOST) {

mMeasureWidth = Math.min(mMeasureWidth, widthSpecSize);

}

}

//测量计算View的高

int heightSpecMode = MeasureSpec.getMode(widthMeasureSpec);

int heightSpecSize = MeasureSpec.getSize(widthMeasureSpec);

if (heightSpecMode == MeasureSpec.EXACTLY) {

//当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小

mMeasureHeight = heightSpecSize;

} else {

//指定默认大小

mMeasureHeight = mDefaultHeight;

if (heightSpecMode == MeasureSpec.AT_MOST) {

mMeasureHeight = Math.min(mMeasureHeight, heightSpecSize);

}

}

mMeasureHeight=mMeasureHeight-getPaddingBottom()-getPaddingTop();

mMeasureWidth=mMeasureWidth-getPaddingLeft()-getPaddingBottom();

//重新测量

setMeasuredDimension(mMeasureWidth, mMeasureHeight);

}

//onSizeChanged() 在控件大小发生改变时调用。所以这里初始化会被调用一次

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mBgRectF = new RectF( -mBgWidth / 2, - mBgHeight / 2, mBgWidth/2, mBgHeight/2);

mMsgTextLength = mTextdPaint.measureText(mMsgText);

//文字的y轴坐标

Paint.FontMetrics fontMetrics = mTextdPaint.getFontMetrics();

mMsgTextHeight = (Math.abs(fontMetrics.ascent) - fontMetrics.descent) / 2;

int[] mMinColors = {Color.YELLOW, Color.GREEN, Color.WHITE, Color.YELLOW};

//先创建一个渲染器

SweepGradient mSweepGradient = new SweepGradient(0,

0, //以圆弧中心作为扫描渲染的中心以便实现需要的效果

mMinColors, //这是我定义好的颜色数组,包含2个颜色:#35C3D7、#2894DD

null);

//把渐变设置到笔刷

mCirclRingPaint.setShader(mSweepGradient);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.translate(mMeasureWidth/2,mMeasureHeight/2);

if (mBgRectF != null) {

canvas.drawRoundRect(mBgRectF,mBgRx,mBgRy,mBackgroundPaint);

}

canvas.drawCircle(0,0,mBgWidth*0.4f,mCirclPaint);

canvas.drawText(mMsgText,-mMsgTextLength/2,mMsgTextHeight,mTextdPaint);

canvas.rotate(mCirclRingRoateAle);

canvas.drawCircle(0,0,mBgWidth*0.34f,mCirclRingPaint);

}

//将设置的db转为屏幕像素

protected int dp2px(int dpVal) {

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,

dpVal, getResources().getDisplayMetrics());

}

public void start(){

mValueAnimator.start();

}

public void close(){

if (mValueAnimator != null) {

mValueAnimator.cancel();

}

}

public boolean isStart() {

return mValueAnimator.isRunning();

}

}

SweepGradient 颜色渲染器,用来实现颜色的过渡

本文同步分享在 博客“早起的年轻人”(CSDN)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值