zoukankan      html  css  js  c++  java
  • Android 自定义View

      最近有看到一个自定义等分圆的View,自己尝试做了一个类似的,效果图如下图(1)所示:

    图(1)

      实现方法:自定义View-ColorCircle,需要的知道的值有圆的半径,等分个数以及扇形颜色。

        /**
         * 定义几种颜色
         */
        private static int COLOR[] = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, Color.BLACK};
        /**
         * 圆等分默认数目
         */
        private static int DIV_SIZE = 3;
    
        private Paint mPaint;
       /** 
       * 圆默认半径
       */
    private static final int DEFAULT_RADIUS = 200; private int mRadius = DEFAULT_RADIUS;
    public ColorCircle(Context context) { this(context, null); } public ColorCircle(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public ColorCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); }

      在onMeasure中我们需要根据widthMeasureSpec & heightMeasureSpec重新计算ColorCircle View的尺寸以及圆的半径(因为默认圆的直径可能会大于View的高 or 宽)。

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    
            int width;
            int height;
    
            if (widthMode == MeasureSpec.EXACTLY) {
                width = widthSize;
            } else {
                width = mRadius * 2 + getPaddingLeft() + getPaddingRight();
                if (widthMode == MeasureSpec.AT_MOST) {
                    width = Math.min(width, widthSize);
                }
            }
    
            if (heightMode == MeasureSpec.EXACTLY) {
                height = heightSize;
            } else {
                height = mRadius * 2 + getPaddingTop() + getPaddingBottom();
                if (heightMode == MeasureSpec.AT_MOST) {
                    height = Math.min(width, heightSize);
                }
            }
    
            setMeasuredDimension(width, height);
            mRadius = (int) (Math.min(width - getPaddingLeft() - getPaddingRight(),
                    height - getPaddingTop() - getPaddingBottom()) * 1.0f / 2);
        }

      最后在onDraw里通过canvas.drawArc()来绘制扇形。

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    //平移Canvas到屏幕中心,之后的绘制以中心点为初始点 canvas.translate((getWidth()
    + getPaddingLeft() - getPaddingRight()) / 2,
                 (getHeight() + getPaddingTop() - getPaddingBottom()) / 2);
    //定义一个RectF对象,表示扇形绘制区域 RectF oval = new RectF(-mRadius, -mRadius, mRadius, mRadius);
    float firstAngle = 0.0f; float divideAngle = (360 * 1.0f) / DIV_SIZE;//根据DIV_SIZE来算每个扇形的角度 for (int i=0; i<DIV_SIZE; i++) { mPaint.setColor(COLOR[i]); canvas.drawArc(oval, (firstAngle + i * divideAngle), divideAngle, true, mPaint); } }

        public void setDivSize(int size){
            DIV_SIZE = size;
            invalidate();
        }

        public int getDivSize(){
            DIV_SIZE = size;
        }
     

      最后还预留了一个setDivSize()接口,方便自定义ColorCircle View动态变化扇形数目。我这里是通过Seekbar来动态切换DIV_SIZE。

        mColorCircle = (ColorCircle)findViewById(R.id.color_circle);
        mSeekBar = (SeekBar)findViewById(R.id.seek_bar);
        mSeekBar.setMax(4);//因为颜色数目原因,这里seekBar的最大值设置为了4。
    int pro = mColorCircle.getSize(); mSeekBar.setProgress(
    pro); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { mColorCircle.setDivSize(progress + 1); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } });

      效果图如下:

     

  • 相关阅读:
    luogu 2617
    BZOJ 3295
    BZOJ 2458
    luogu 3810
    Uva
    Uva
    Uva
    Uva
    Uva
    成员函数的const到底修饰的是谁
  • 原文地址:https://www.cnblogs.com/Peter-Chen/p/7082664.html
Copyright © 2011-2022 走看看