Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 自定義View練習:雷達圖(比重)繪制

Android 自定義View練習:雷達圖(比重)繪制

編輯:關於Android編程

這裡寫圖片描述

code:

package com.louisgeek.louiscustomviewstudy;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import static android.content.ContentValues.TAG;

/**
 * Created by louisgeek on 2016/10/27.
 */

public class RadarView08 extends View {
    private Paint mPaint;
    private int mViewWidth, mViewHeight,mScreenWidth,mScreenHeight;
    /**
     *文字與邊緣點的距離
     */
    private final float mText_ContentDisance = 10;
    /**
     *線的粗細
    */
    private  int mLinesWidth = this.dp2px(1);

    //順時針  對應的數據
    // private float[] mDataValue={1f,1f,1f,1f,0.8f,0.6f,0.4f,1f,0.4f,1f};//10
    private float[] mDataValue = {1f, 0.1f, 1f, 1f, 0.8f, 0.6f, 0.4f, 0.4f};//8
    //private float[] mDataValue={1f,0.8f,0.6f,0.4f,1f,0.4f};//6
    // private float[] mDataValue={1f,0.8f,0.6f,0.4f};//4
    // private float[] mDataValue={1f,1f,1f};//3
    private String[] mDataName = {"豌豆莢", "應用寶", "百度91安卓", "安智市場", "小米應用商店", "OPPO應用商店", "魅族應用商店", "360手機助手", "華為應用市場", "移動MM商店"};

    /**
     * 最大形狀的半徑
     */
   private int mRadius = this.dp2px(50);//max
    /**
     * 小圓點半徑
     */
    private int mPointRadius = this.dp2px(2);
    private int mPointColor = Color.GRAY;

    private int mContentColor=Color.BLUE;
    private int mLinesColor=Color.LTGRAY;
    private int mTextColor=Color.RED;
    private int mTextSize=this.dp2px(14);
    /**
     * 角度
     */
    private int mDegreesAngle;
    private int mContentAlpha=150;//must in (0-225)
    //點的數量
    private int mPointsCount;

    private Paint mPaintText=new Paint();

    private  Context mContext;

    public RadarView08(Context context) {
        this(context, null);
    }

    public RadarView08(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RadarView08(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext=context;
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.RadarView08);
       mLinesWidth = ta.getDimensionPixelOffset(R.styleable.RadarView08_linesWidth, mLinesWidth);
        mRadius = ta.getDimensionPixelOffset(R.styleable.RadarView08_maxCircleRadius, mRadius);
        mPointRadius = ta.getDimensionPixelOffset(R.styleable.RadarView08_pointRadius, mPointRadius);
        mContentColor = ta.getColor(R.styleable.RadarView08_contentColor, mContentColor);
        mPointColor = ta.getColor(R.styleable.RadarView08_pointColor, mPointColor);
        mLinesColor = ta.getColor(R.styleable.RadarView08_linesColor, mLinesColor);
        mContentAlpha = ta.getInteger(R.styleable.RadarView08_contentAlpha, mContentAlpha);
        mTextColor = ta.getColor(R.styleable.RadarView08_titleColor, mTextColor);
        mTextSize = ta.getDimensionPixelOffset(R.styleable.RadarView08_titleTextSize, mTextSize);
        //
        ta.recycle();
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.LTGRAY);
        mPaint.setStrokeWidth(mLinesWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        //
        mPaintText=new Paint();
        mPaintText.setColor(mTextColor);
        mPaintText.setTextSize(mTextSize);
        mPaintText.setAntiAlias(true);
        mPaintText.setStyle(Paint.Style.FILL);


        //must in (0-225)
        mContentAlpha=mContentAlpha<0?0:mContentAlpha;
        mContentAlpha=mContentAlpha>255?255:mContentAlpha;
        Log.d(TAG, "init: mContentAlpha:"+mContentAlpha);
        //
        mPointsCount = mDataValue.length;
        mDegreesAngle = 360 / mPointsCount;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         /*mWidth =getMeasuredWidth();
         mHeight = getMeasuredHeight();*/

//        mScreenWidth=getScreenWidth(mContext);
//        mScreenHeight=getScreenHeight(mContext);
       /* int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);*/



        int maxLen=0;
        String maxLenName=mDataName[0];
        for (int i = 0; i < mDataValue.length; i++) {
           int len= mDataName[i].length();
            if (len>maxLen){
                maxLen=len;
                maxLenName=mDataName[i];
            }

        }
        float fixWidth_Height=mPaintText.measureText(maxLenName);
        /**
         * 實際的內容寬和高
         */
        int contentWidthSize = (int) (fixWidth_Height*2+mRadius*2+Math.max(mPointRadius,mLinesWidth)*1.0f/2+this.getPaddingLeft()+this.getPaddingRight());
        int contentHeightSize = (int) (fixWidth_Height*2+mRadius*2+Math.max(mPointRadius,mLinesWidth)*1.0f/2+this.getPaddingTop()+this.getPaddingBottom());


        //getDefaultSize()
        int width = resolveSize(contentWidthSize, widthMeasureSpec);
        int height = resolveSize(contentHeightSize, heightMeasureSpec);

        /**
         * 修正xml設置太小的情況
         */
        width=width<contentwidthsize?contentwidthsize:width; height="height<contentHeightSize?contentHeightSize:height;" mviewwidth="" mviewheight="height;" override="" protected="" void="" canvas="" if="" mpointscount=""> 10 || mPointsCount < 3) {
            Log.e(TAG, "onDraw: 只能是3~10個數據");
            return;
        }
        drawFramesAndLines(canvas);
        //
        drawContent(canvas);

        drawTexts(canvas);
    }

    private void drawContent(Canvas canvas) {
        Paint paintContent = new Paint();
        //paintContent.setColor(mContentColor);
        paintContent.setAntiAlias(true);
        paintContent.setStyle(Paint.Style.FILL);
        paintContent.setStrokeCap(Paint.Cap.ROUND);
        Path path = new Path();

        for (int i = 0; i < mPointsCount; i++) {
            //!!!加上原有占width的筆觸  mPointsCount-1條線 mLineWidth/2*(mPointsCount-1)
            float nowContentDisance = (mRadius - mLinesWidth / 2) * mDataValue[i];
            if (i == 0) {
                path.moveTo(nowContentDisance, 0);
                //繪制小圓點
                paintContent.setColor(mPointColor);
                canvas.drawCircle(nowContentDisance, 0, mPointRadius, paintContent);
            } else {
                float nowDegreesAngle = mDegreesAngle * i;
                double nowRadiansAngle = Math.toRadians(nowDegreesAngle);
                //sinA=對邊/Radius
                //cosA=領邊/Radius
                float tempX = (float) (nowContentDisance * Math.cos(nowRadiansAngle));
                float tempY = (float) (nowContentDisance * Math.sin(nowRadiansAngle));
                path.lineTo(tempX, tempY);
                //繪制小圓點
                paintContent.setColor(mPointColor);
                canvas.drawCircle(tempX, tempY, mPointRadius, paintContent);
            }
        }
        paintContent.setColor(mContentColor);
        paintContent.setAlpha(mContentAlpha);
        canvas.drawPath(path, paintContent);
    }

    /**
     * 繪制文字
     */
    private void drawTexts(Canvas canvas) {
       /* Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        float fontHeight = fontMetrics.descent - fontMetrics.ascent;*/

        /**
         * 參考圓
         */
        //###canvas.drawCircle(0,0,mRadius+mText_ContentDisance,mPaint);

        for (int i = 0; i < mPointsCount; i++) {
            if (i == 0) {
                //獲取文字度量信息
                Paint.FontMetrics fontMetrics = mPaintText.getFontMetrics();
                float textHeight = fontMetrics.descent - fontMetrics.ascent;
                float baseLineYDis = textHeight / 2 - Math.abs(fontMetrics.descent);
                float tempXFix = mText_ContentDisance;
                float tempYFix = baseLineYDis;
                canvas.drawText(mDataName[i], mRadius + tempXFix, 0 + tempYFix, mPaintText);
            } else {
                float nowDegreesAngle = mDegreesAngle * i;
                double nowRadiansAngle = Math.toRadians(nowDegreesAngle);
                //sinA=對邊/Radius
                //cosA=領邊/Radius
                float tempX = (float) (mRadius * Math.cos(nowRadiansAngle));
                float tempY = (float) (mRadius * Math.sin(nowRadiansAngle));
                //
               /* Rect rect_bounds=new Rect();
                paintText.getTextBounds(mDataName[i],0,mDataName[i].length(),rect_bounds);
                int textWidth=rect_bounds.width();
                int textHeight=rect_bounds.height();*/
                //獲取文字度量信息
                Paint.FontMetrics fontMetrics = mPaintText.getFontMetrics();
                float textHeight = fontMetrics.descent - fontMetrics.ascent;
                float textWidth = mPaint.measureText(mDataName[i]);

                float baseLineYDis = textHeight / 2 - Math.abs(fontMetrics.descent);
                float tempXFix;
                float tempYFix;
                if (nowDegreesAngle > 0 && nowDegreesAngle <= 90) {
                    tempXFix = mText_ContentDisance - textWidth / 2;
                    tempYFix = mText_ContentDisance + textHeight / 2 + baseLineYDis;
                    canvas.drawText(mDataName[i], tempX + tempXFix, tempY + tempYFix, mPaintText);
                } else if (nowDegreesAngle > 90 && nowDegreesAngle < 180) {
                    tempXFix = mText_ContentDisance + textWidth;
                    tempYFix = mText_ContentDisance + textHeight / 2 + baseLineYDis;
                    canvas.drawText(mDataName[i], tempX - tempXFix, tempY + tempYFix, mPaintText);
                } else if (nowDegreesAngle == 180) {
                    //###tempXFix=mText_ContentDisance+textWidth;//這裡感覺計算不准 改變計算方式彌補下
                    /** 換個計算方法*/
                    Rect rectBounds = new Rect();
                    mPaintText.getTextBounds(mDataName[i], 0, mDataName[i].length(), rectBounds);
                    int textNewWidth = rectBounds.width();
                    tempXFix = mText_ContentDisance + textNewWidth;
                    tempYFix = baseLineYDis;
                    //mRadius
                    canvas.drawText(mDataName[i], -mRadius - tempXFix, 0 + tempYFix, mPaintText);
                } else if (nowDegreesAngle > 180 && nowDegreesAngle <= 270) {
                    tempXFix = mText_ContentDisance + textWidth;
                    tempYFix = mText_ContentDisance + textHeight / 2 - baseLineYDis;
                    canvas.drawText(mDataName[i], tempX - tempXFix, tempY - tempYFix, mPaintText);
                } else if (nowDegreesAngle > 270 && nowDegreesAngle <= 360) {
                    tempXFix = mText_ContentDisance - textWidth / 2;
                    tempYFix = mText_ContentDisance + textHeight / 2 - baseLineYDis;
                    canvas.drawText(mDataName[i], tempX + tempXFix, tempY - tempYFix, mPaintText);
                }
            }
        }


    }

    private void drawFramesAndLines(Canvas canvas) {
        Path path = new Path();
        int mDisance = mRadius / (mPointsCount - 1);
        /**
         * 循環出多個正六邊形
         */
        for (int j = 0; j < mPointsCount - 1; j++) {
            float nowRadius = mDisance * ((mPointsCount - 1) - j);

            /**
             * 畫每一個正六邊形
             */
            for (int i = 0; i < mPointsCount; i++) {
                // path.reset();
                /**
                 * 順時針  從最右邊畫
                 */
                if (i == 0) {
                    path.moveTo(nowRadius, 0);

                    /**
                     * 畫從中點到最右邊點的線
                     */
                    Path pathLines = new Path();
                    pathLines.lineTo(nowRadius, 0);
                    mPaint.setColor(mLinesColor);
                    canvas.drawPath(pathLines, mPaint);
                } else {
                    float nowDegreesAngle = mDegreesAngle * i;
                    double nowRadiansAngle = Math.toRadians(nowDegreesAngle);
                    //sinA=對邊/Radius
                    //cosA=領邊/Radius
                    float tempX = (float) (nowRadius * Math.cos(nowRadiansAngle));
                    float tempY = (float) (nowRadius * Math.sin(nowRadiansAngle));
                    path.lineTo(tempX, tempY);
                    /**
                     * 畫從當前點到中點的線
                     */
                    Path pathLines = new Path();
                    pathLines.moveTo(tempX, tempY);
                    pathLines.lineTo(0, 0);
                    mPaint.setColor(mLinesColor);
                    canvas.drawPath(pathLines, mPaint);
                }

            }
            //
            path.close();
            //
            canvas.drawPath(path, mPaint);
        }
    }

    //
    public int dp2px(int dpValue) {
        int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, getResources().getDisplayMetrics());
        return px;
    }
    //獲取屏幕的寬度
    public static int getScreenWidth(Context context) {
        Resources resources = context.getResources();
        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        float density = displayMetrics.density;
        int width = displayMetrics.widthPixels;
        int height = displayMetrics.heightPixels;
        return width;
    }

    //獲取屏幕的高度
    public static int getScreenHeight(Context context) {
        Resources resources = context.getResources();
        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        float density = displayMetrics.density;
        int width = displayMetrics.widthPixels;
        int height = displayMetrics.heightPixels;
        return height;
    }
}
</contentwidthsize?contentwidthsize:width;>
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved