Android N 边形 View

作者: markRao | 来源:发表于2021-05-24 14:47 被阅读0次

    需求千奇百怪,对于登录后账户的头像,要求圆形、多边形、带描边、带 VIP 标示等等,所以实现一个 N 边形玩玩,效果和代码如下。

    多边形各顶点计算公式如下:
    (1)正多边形的中心点为(0,0)
    for (i = 0; i < n; i++) {
      printf("%f %f\n", r * Math.cos(2 * Math.PI * i / n), r * Math.sin(2 * Math.PI * i / n));
    }
    x轴坐标为 r * Math.cos(2 * Math.PI * i / n)
    y轴坐标为 r * Math.sin(2 * Math.PI * i / n)
    
    (2)正多边形的中心点为(a,b)
    for (i = 0; i < n; i++) {
      printf("%f %f\n",a + r * Math.cos(2 * Math.PI * i / n), b+ r * Math.sin(2 * Math.PI * i / n));
    }
    
    x轴坐标为 a + r * Math.cos(2 * Math.PI * i / n)
    y轴坐标为 b + r * Math.sin(2 * Math.PI * i / n)
    

    算法原文链接:https://blog.csdn.net/wuprogrammer/article/details/108903244

    12 边形
    public class TestView extends View {
    
        private static final int DEF_SIDE_LENGTH = 6;
        private static final int DEF_SIZE = 66;
        private int sideLength;
        private Paint paint;
        private Context context;
        private Path path;
        private int bgRes;
        private int radius;
    
        public TestView(Context context) {
            super(context);
            init(context, null);
        }
    
        public TestView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init(context, attrs);
        }
    
        public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs);
        }
    
        private void init(Context context, @Nullable AttributeSet attrs) {
            this.context = context;
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TestView);
            sideLength = typedArray.getInt(R.styleable.TestView_side_length, DEF_SIDE_LENGTH);
            bgRes = typedArray.getResourceId(R.styleable.TestView_bg_res, 0);
            typedArray.recycle();
            if(bgRes != 0){
                initPaint();
            }
        }
    
        private void initPaint() {
            paint = new Paint();
            paint.setColor(ContextCompat.getColor(context, android.R.color.black));
            paint.setStrokeWidth(10f);
            paint.setAntiAlias(true);
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), bgRes);
            BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint.setShader(shader) ;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if(bgRes == 0){
                return;
            }
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            if(widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY){
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = MeasureSpec.getSize(heightMeasureSpec);
                radius = Math.min(width, height) / 2;
            }else {
                float scale = context.getResources().getDisplayMetrics().density;
                int size = (int) (DEF_SIZE * scale + 0.5f);
                radius = size / 2;
                widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
                setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
            }
            initPoint();
        }
    
    
        public void setSideLength(int sideLength) {
            this.sideLength = sideLength;
            initPoint();
            invalidate();
        }
    
        private void initPoint() {
            if(null == path){
                path = new Path();
            }
            path.reset();
            for (int i = 1; i <= sideLength; i++) {
               float x = (float)(radius * Math.cos(2 * Math.PI * i / sideLength)) + radius;
                float y = (float)(radius * Math.sin(2 * Math.PI * i / sideLength)) + radius;
                if(i == 1){
                    path.moveTo(x, y);
                }else {
                    path.lineTo(x, y);
                }
            }
            path.close();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(bgRes != 0){
                canvas.drawPath(path, paint);
            }
        }
    
    }
    

    自定义属性如下

     <declare-styleable name="TestView">
            <attr name="side_length" format="integer" />
            <attr name="bg_res" format="reference" />
        </declare-styleable>
    

    相关文章

      网友评论

        本文标题:Android N 边形 View

        本文链接:https://www.haomeiwen.com/subject/yhexsltx.html