android 使用canvas绘制正多边行

我们先重温初中生都知道的几个概念

正多边行每个圆心角都是相等的,也就是360/n(n是指多少边行) 

二个相邻的点构成的线是相等的

见图:


然后通过Path,把相邻的二个点连接起来就形成了一个Path,绘制到画布(canvas)就ok,

代码如下:

package com.multilateral.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by zhouguizhi on 2017/9/25.
 */
public class CustomMultilateralView extends View {
    private Paint paint;
    private int number = 8;//8边形
    private float STROKEWIDTH = 4;
    private float STROKEWIDTH_LINE = 2;
    private boolean isDrawCircle = true;//是否绘制外圆
    private boolean isJoinLine = true;
    private Map<Float,Float> points ;
    private float centerX;
    private float centerY;
    public CustomMultilateralView(Context context) {
        this(context,null);
    }
    public CustomMultilateralView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }
    public CustomMultilateralView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomMultilateralView);
        number = typedArray.getInteger(R.styleable.CustomMultilateralView_number, 4);
        isDrawCircle = typedArray.getBoolean(R.styleable.CustomMultilateralView_isDrawCircle,isDrawCircle);
        isJoinLine = typedArray.getBoolean(R.styleable.CustomMultilateralView_isjoinLine,isJoinLine);
        typedArray.recycle();
        init();
        points = new HashMap<>();
    }
    private void init() {
        paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(STROKEWIDTH);
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        if(number < 3) {
            return;
        }
        drawCircle(canvas);
        drawPath(canvas);
        drawJoinLines(canvas);
    }

    private void drawJoinLines(Canvas canvas) {
        if(null==canvas){
            return;
        }
        paint.setStrokeWidth(STROKEWIDTH_LINE);
        for (Map.Entry<Float, Float> entry: points.entrySet()) {
            canvas.drawLine(centerX,centerY,entry.getKey(),entry.getValue(),paint);
        }
    }

    private void drawPath(Canvas canvas) {
        if(null==canvas){
            return;
        }
        paint.setStrokeWidth(STROKEWIDTH);
        float radius = getHeight() / 2-2;
        centerX = getMeasuredHeight()/2;
        centerY = getMeasuredHeight()/2;
        Path path = new Path();
        for (int i = 0; i <=number; i++) {
            float alpha = Double.valueOf(((2f / number) * i) * Math.PI).floatValue();//2π/n是求出每一个圆心角的角度
            float nextX = centerX + Double.valueOf(radius * Math.cos(alpha)).floatValue();
            float nextY = centerY + Double.valueOf(radius * Math.sin(alpha)).floatValue();
            points.put(nextX,nextY);
            if (i == 0) {
                path.moveTo(nextX, nextY);
            } else {
                path.lineTo(nextX, nextY);
            }
        }
        canvas.drawPath(path, paint);
    }

    private void drawCircle(Canvas canvas) {
        if(null==canvas){
            return;
        }
        if(isDrawCircle){
            canvas.drawCircle(getMeasuredHeight()/2,getMeasuredHeight()/2,getMeasuredHeight()/2-STROKEWIDTH/2,paint);
        }
    }

}
attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomMultilateralView">
        <attr name="number" format="integer" />
        <attr name="isDrawCircle" format="boolean"></attr>
        <attr name="isjoinLine" format="boolean"></attr>
    </declare-styleable>
</resources>
布局文件:

扫描二维码关注公众号,回复: 1163230 查看本文章

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:zhou="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <com.multilateral.view.CustomMultilateralView
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_centerInParent="true"
        zhou:number="12"
        zhou:isDrawCircle="false"
        zhou:isjoinLine="true"
         />
</RelativeLayout>
效果图:



猜你喜欢

转载自blog.csdn.net/coderinchina/article/details/78090841
今日推荐