android自定义view实现圆环效果
发布日期:2021-05-09 18:26:46 浏览次数:11 分类:精选文章

本文共 6681 字,大约阅读时间需要 22 分钟。

先上规矩吧:

         

重要的是如何实现自定义的view效果

(1)创建类,继承view,重写onDraw和onMesure方法

public class CirclePercentBar extends View{    private Context mContext;    private int mArcColor;    private int mArcWidth;    private int mCenterTextColor;    private int mCenterTextSize;    private int mCircleRadius;    private Paint arcPaint;    private Paint arcCirclePaint;    private Paint centerTextPaint;    private RectF arcRectF;    private Rect textBoundRect;    private float mCurData=0;    private int arcStartColor;    private int arcEndColor;    private Paint startCirclePaint;    public CirclePercentBar(Context context) {        this(context, null);    }    public CirclePercentBar(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CirclePercentBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mContext=context;        TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.CirclePercentBar,defStyleAttr,0);        mArcColor = typedArray.getColor(R.styleable.CirclePercentBar_arcColor,0xff0000);        mArcWidth = typedArray.getDimensionPixelSize(R.styleable.CirclePercentBar_arcWidth, DisplayUtil.dp2px(context, 20));        mCenterTextColor = typedArray.getColor(R.styleable.CirclePercentBar_centerTextColor, 0x0000ff);        mCenterTextSize = typedArray.getDimensionPixelSize(R.styleable.CirclePercentBar_centerTextSize, DisplayUtil.dp2px(context, 20));        mCircleRadius = typedArray.getDimensionPixelSize(R.styleable.CirclePercentBar_circleRadius, DisplayUtil.dp2px(context, 100));        arcStartColor = typedArray.getColor(R.styleable.CirclePercentBar_arcStartColor,                ContextCompat.getColor(mContext, R.color.green));        arcEndColor = typedArray.getColor(R.styleable.CirclePercentBar_arcEndColor,                ContextCompat.getColor(mContext, R.color.yellow));        typedArray.recycle();        initPaint();    }    private void initPaint() {        startCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        startCirclePaint.setStyle(Paint.Style.FILL);        //startCirclePaint.setStrokeWidth(mArcWidth);        startCirclePaint.setColor(arcStartColor);        arcCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        arcCirclePaint.setStyle(Paint.Style.STROKE);        arcCirclePaint.setStrokeWidth(mArcWidth);        arcCirclePaint.setColor(ContextCompat.getColor(mContext,R.color.colorAccent));        arcCirclePaint.setStrokeCap(Paint.Cap.ROUND);        arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        arcPaint.setStyle(Paint.Style.STROKE);        arcPaint.setStrokeWidth(mArcWidth);        arcPaint.setColor(mArcColor);        arcPaint.setStrokeCap(Paint.Cap.ROUND);        centerTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        centerTextPaint.setStyle(Paint.Style.STROKE);        centerTextPaint.setColor(mCenterTextColor);        centerTextPaint.setTextSize(mCenterTextSize);        //圓弧的外接矩形        arcRectF = new RectF();        //文字的边界矩形        textBoundRect = new Rect();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(measureDimension(widthMeasureSpec),measureDimension(heightMeasureSpec));    }    private int measureDimension(int measureSpec) {        int result;        int specMode=MeasureSpec.getMode(measureSpec);        int specSize=MeasureSpec.getSize(measureSpec);        if(specMode==MeasureSpec.EXACTLY){            result=specSize;        }else{            result=mCircleRadius*2;            if(specMode==MeasureSpec.AT_MOST){                result=Math.min(result,specSize);            }        }        return result;    }    @Override    protected void onDraw(Canvas canvas) {        canvas.rotate(-90, getWidth()/ 2, getHeight()/ 2);        arcRectF.set(getWidth()/2-mCircleRadius+mArcWidth/2,getHeight()/2-mCircleRadius+mArcWidth/2                ,getWidth()/2+mCircleRadius-mArcWidth/2,getHeight()/2+mCircleRadius-mArcWidth/2);        canvas.drawArc(arcRectF, 0,360,false,arcCirclePaint);        arcPaint.setShader(new SweepGradient(getWidth()/2,getHeight()/2,arcStartColor,arcEndColor));        canvas.drawArc(arcRectF, 0,360* mCurData /100,false,arcPaint);        canvas.rotate(90, getWidth()/ 2, getHeight()/ 2);        canvas.drawCircle(getWidth()/2,getHeight()/2-mCircleRadius+mArcWidth/2,mArcWidth/2,startCirclePaint);        String data= String.valueOf(mCurData) +"%";        centerTextPaint.getTextBounds(data,0,data.length(),textBoundRect);        canvas.drawText(data,getWidth()/2-textBoundRect.width()/2,getHeight()/2+textBoundRect.height()/2,centerTextPaint);    }    public void setPercentData(float data, TimeInterpolator interpolator){        ValueAnimator valueAnimator=ValueAnimator.ofFloat(mCurData,data);        valueAnimator.setDuration((long) (Math.abs(mCurData-data)*30));        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator valueAnimator) {                float value= (float) valueAnimator.getAnimatedValue();                mCurData=(float)(Math.round(value*10))/10;                invalidate();            }        });        valueAnimator.setInterpolator(interpolator);        valueAnimator.start();    }}

 

 

(2)其中需要用到的类

public class DisplayUtil {    public static int px2dp(Context context,float pxValue){        final float scale=context.getResources().getDisplayMetrics().density;        return (int)(pxValue/scale+0.5f);    }    public static int dp2px(Context context,float dpValue){        final float scale=context.getResources().getDisplayMetrics().density;        return (int)(dpValue*scale+0.5f);    }}

(3)attrs.xml

(4)在activity_main里面写布局

(6)编程实现效果:

public class MainActivity extends AppCompatActivity {    CirclePercentBar circlePercentBar;    Button startBtn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        circlePercentBar= (CirclePercentBar) findViewById(R.id.circle_bar);        circlePercentBar.setPercentData(55.2f,new DecelerateInterpolator());        startBtn= (Button) findViewById(R.id.start_btn);        startBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                circlePercentBar.setPercentData((float) (100*Math.random()),new DecelerateInterpolator());            }        });    }}

 

 

上一篇:seekbar简单使用(一)
下一篇:java遍历的三种形式

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月10日 05时07分56秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章