环形统计图:

效果图片(实例中有动画效果)

 

以下是自定义view代码(闲时写的栗子,未做适配,项目已托管github,,见文末)

public class AnnularView extends View {    private float sum;//总数    private Context context;    //屏幕宽高    //  private float width;    //  private float height;    //画笔    private Paint mPaint;    private Paint mPaint1;    private Paint mPaint2;    private Paint textPaint;    //控件宽高    private int mWith;    private int mHeight;    //圆直径    private float diameter;    private Rect oRect;    private Paint tPaint;    private int multiple = 1;    private Float[] datas = new Float[]{20f, 50f, 70f, 100f, 10f, 30f};    private Float[] angle;    // private Float[] names = new Float[]{20f, 50f, 70f, 100f, 10f, 30f};    private String[] colorstr = new String[]{            "#99ff66", "#ffff66", "#ff9966",            "#ff3366", "#ccff99", "#cc6699",            "#999999", "#33cc99", "#003399",            "#ff33cc", "#cccccc", "#99cccc"};    private Float startAngle = 0f, sweepAngle = 0f;    private int angleColor;    private int overallMultiple = 150;    private List regionList;    private int index = -1;    public AnnularView(Context context) {        super(context);        this.context = context;    }    public AnnularView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        this.context = context;        init();        initdata();    }    private void initdata() {        //    angle = new Float[datas.length];        //    for (int i = 0; i < datas.length; i++) {        //        sum = sum + datas[i];        //    }        //    for (int i = 0; i < datas.length; i++) {        //        angle[i] = 360 * (datas[i] / sum);        //    }    }    private void init() {        regionList = new ArrayList<>();        mPaint = new Paint();        mPaint.setColor(Color.BLACK);       //设置画笔颜色        mPaint.setStyle(Paint.Style.FILL);  //设置画笔模式为填充        mPaint.setStrokeWidth(1f);//设置画笔宽度为10px        //mPaint.setAlpha(250);        mPaint.setAntiAlias(true);        textPaint = new Paint();        textPaint.setColor(Color.BLACK);        textPaint.setStyle(Paint.Style.STROKE);        textPaint.setTextSize(30);        textPaint.setAntiAlias(true);        textPaint.setStrokeWidth(5f);        mPaint1 = new Paint();        mPaint1.setColor(Color.WHITE);       //设置画笔颜色        mPaint1.setStyle(Paint.Style.FILL);  //设置画笔模式为填充        mPaint1.setStrokeWidth(5f);         //设置画笔宽度为10px        // mPaint1.setAlpha(115);        mPaint1.setAntiAlias(true);        mPaint2 = new Paint();        mPaint2.setColor(Color.WHITE);       //设置画笔颜色        mPaint2.setStyle(Paint.Style.STROKE);  //设置画笔模式为填充        mPaint2.setStrokeWidth(5f);         //设置画笔宽度为10px        // mPaint1.setAlpha(115);        mPaint2.setAntiAlias(true);        getScreenSize();        //-------------        oRect = new Rect();        tPaint = new Paint();        tPaint.setAntiAlias(true);        tPaint.setStyle(Paint.Style.FILL);        tPaint.setTextSize(30);        tPaint.setColor(Color.BLACK);        tPaint.setAntiAlias(true);        tPaint.setStrokeWidth(4);    }    /**     * 获取屏幕宽高     */    private void getScreenSize() {        Resources resources = this.getResources();        DisplayMetrics dm = resources.getDisplayMetrics();        float density = dm.density;        // width = dm.widthPixels;        // height = dm.heightPixels;        // diameter = width * 9f / 10f;//        float screenWidth = dm.widthPixels * density;        float screenHeight = dm.heightPixels * density;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWith = MeasureSpec.getSize(widthMeasureSpec);    //取出宽度的确切数值        mHeight = MeasureSpec.getSize(heightMeasureSpec);    //取出高度的确切数值        diameter = mWith > mHeight ? mHeight * 9 / 10 : mWith * 9 / 10;    }    private void drawArc(Canvas canvas, RectF rectF, float startAngle, float sweepAngle, int color) {        Path rectFPath = new Path();        rectFPath.moveTo(0, 0);        // rectFPath.moveTo(width / 2, width / 2 + height / 20);        rectFPath.lineTo(((float) Math.cos(Math.toRadians(startAngle))) * diameter / 2,                ((float) Math.sin(Math.toRadians(startAngle))) * diameter / 2);        RectF rect = new RectF(-diameter / 2, -diameter / 2, diameter / 2, diameter / 2);        rectFPath.addArc(rect, startAngle,                sweepAngle);        rectFPath.lineTo(0, 0);        rectFPath.close();        rectFPath.computeBounds(rect, true);        // rectFPath.moveTo(width / 2, width / 2 + height / 20);        Region mRegion = new Region();        mRegion.setPath(rectFPath, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));        if (overallMultiple == multiple) {            regionList.add(mRegion);        }        mPaint.setColor(color);        canvas.drawArc(rectF, startAngle, sweepAngle, true, mPaint);        canvas.drawArc(rectF, startAngle, sweepAngle, true, mPaint2);        drawArcText(canvas, ((int) (sweepAngle / 360 * 10000)) / 100f + "%", ((float) Math.cos(Math.toRadians(startAngle + sweepAngle / 2))) * diameter * 4 / 10,                ((float) Math.sin(Math.toRadians(startAngle + sweepAngle / 2))) * diameter * 4 / 10);    }    private void drawCentreText(Canvas canvas, String text) {        tPaint.getTextBounds(text, 0, text.length(), oRect);        tPaint.setColor(Color.BLACK);        /*         * 控件宽度/2 - 文字宽度/2         */        float v = tPaint.measureText(text);//文字宽度        float startX = -v / 2;        /*         * 控件高度/2 + 文字高度/2,绘制文字从文字左下角开始,因此"+"         */        // float startY = getHeight() / 2 + oRect.height() / 2;        Paint.FontMetricsInt fm = tPaint.getFontMetricsInt();        //fm.bottom - fm.top//文字高度        int startY = -fm.descent + (fm.bottom - fm.top) / 2;        // 绘制文字        canvas.drawText(text, startX, startY, tPaint);    }    private void drawArcText(Canvas canvas, String text, Float CentreX, Float CentreY) {        tPaint.getTextBounds(text, 0, text.length(), oRect);        tPaint.setColor(Color.WHITE);        /*         * 控件宽度/2 - 文字宽度/2         */        float v = tPaint.measureText(text);//文字宽度        float startX = -v / 2;        /*         * 控件高度/2 + 文字高度/2,绘制文字从文字左下角开始,因此"+"         */        // float startY = getHeight() / 2 + oRect.height() / 2;        Paint.FontMetricsInt fm = tPaint.getFontMetricsInt();        //fm.bottom - fm.top//文字高度        int startY = -fm.descent + (fm.bottom - fm.top) / 2;        // 绘制文字        canvas.drawText(text, startX + CentreX, startY + CentreY, tPaint);    }    @RequiresApi(api = Build.VERSION_CODES.KITKAT)    @Override    protected void onDraw(final Canvas canvas) {        super.onDraw(canvas);        canvas.translate(mWith / 2, mHeight / 2);        if (angle == null) {            return;        }        //final RectF rectF = new RectF(-diameter / 2, -diameter / 2, diameter / 2, diameter / 2);        final RectF rectF = new RectF();        if (regionList != null) {            regionList.clear();        }        Float Angle = 0f;        for (int i = 0; i < angle.length; i++) {            Angle = i > 0 ? angle[i - 1] + Angle : 0;            //Log.e("-----startAngle=", Angle + "");            startAngle = Angle;            sweepAngle = angle[i];            angleColor = Color.parseColor(colorstr[i]);            Float sta = startAngle * multiple / overallMultiple;            Float swa = sweepAngle * multiple / overallMultiple;            if (index == i) {                rectF.set(-diameter / 2 - 10, -diameter / 2 - 10, diameter / 2 + 10, diameter / 2 + 10);                // index = -1;            } else {                rectF.set(-diameter / 2, -diameter / 2, diameter / 2, diameter / 2);            }            drawArc(canvas, rectF, sta,                    swa, angleColor);        }        LinearGradient backGradient = new LinearGradient(diameter / 2, -diameter / 2, -diameter / 2, diameter / 2,                new int[]{ContextCompat.getColor(context, R.color.colorStart),                        // ContextCompat.getColor(context, R.color.color1),                        ContextCompat.getColor(context, R.color.colorEnd)},                null, Shader.TileMode.CLAMP);        mPaint1.setShader(backGradient);        // 绘制圆        // mPaint.setColor(Color.WHITE);        canvas.drawCircle(0, 0, diameter * 3 / 10, mPaint1);        // 绘制圆        mPaint.setColor(Color.WHITE);        canvas.drawCircle(0, 0, diameter * 3 / 10 * 17 / 18, mPaint);        drawCentreText(canvas, "环形图");    }    private final int ACTION_CLICK = 1;//点击    private final int ACTION_MOVE = 2;//滑动    private int action;    @Override    public boolean onTouchEvent(MotionEvent event) {        // Log.e(TAG, "onTouchEvent:  x=" + event.getX() + " y=" + event.getY());        Float dwX, dwY;        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                dwX = event.getX();                dwY = event.getY();                action = ACTION_CLICK;                break;            case MotionEvent.ACTION_MOVE:                // action = ACTION_MOVE;                break;            case MotionEvent.ACTION_UP:                switch (action) {                    case ACTION_CLICK:                        for (int i = 0; i < regionList.size(); i++) {                            if (regionList.get(i).contains((int) (event.getX() - (mWith / 2)), (int) (event.getY() - (mHeight / 2)))) {                                if (index == i) {                                    index = -1;                                } else {                                    index = i;                                }                                // invalidate();                                break;                            }                            //Log.e(TAG, "onTouchEvent: oo=" + index);                        }                        //  Log.e(TAG, "onTouchEvent: action=" + action);                        invalidate();                        break;                }                break;        }        return true;    }    private Boolean isDynamic = false;    public void setDatas(Float[] datas, Boolean isDynamic) {        if (angle == null) {            angle = new Float[datas.length];        }        for (int i = 0; i < datas.length; i++) {            sum = sum + datas[i];        }        for (int i = 0; i < datas.length; i++) {            angle[i] = 360 * (datas[i] / sum);        }        this.isDynamic = isDynamic;        //invalidate();        if (isDynamic) {            thread.start();        }    }    public void stapThread() {        if (thread.isAlive()) {            isDynamic = false;        }    }    private int time = 5;    private Thread thread = new Thread(new Runnable() {        public void run() {            for (int j = 1; j <= overallMultiple; j++) {                handler.sendEmptyMessage(0x10);                if (!isDynamic) {                    return;                }                multiple = j;                try {                    Thread.sleep(time);                } catch (InterruptedException e) {                    e.printStackTrace();                }                if (j > overallMultiple * 7 / 8)                    time += 1;            }        }    });    Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            if (msg.what == 0x10)                invalidate();        }    };}

代码简单就不做解释分析,

具体使用参见github项目地址:https://github.com/xxfen/CustomCartogram

如有疑问可滴滴我,

感谢阅读。

 

 

 

更多相关文章

  1. android 实现在文本内容超过固定宽度可手动左右滚动查看效果
  2. Android使用NinePatch图片实现大小可变的Button
  3. Android中自定义ViewGroup实现表格展示学员信息
  4. Android之解决多语言适配部分TextView内容左对齐和内容一行不排
  5. Android具有粘性的小球,跌落反弹形成文字的动画效果
  6. Android(安卓)TextView文字滚动
  7. 【Android】TextView倾斜文字
  8. Android(安卓)图片文字单位 px、dp、sp区别
  9. Android(安卓)dp方式的屏幕适配工具使用(bat批处理方式)

随机推荐

  1. android发送restful风格的http请求
  2. Android应用程序键盘(Keyboard)消息处理机
  3. 阅读《Android 从入门到精通》(31)——Inte
  4. FregServer进程,获取ServiceManager代理对
  5. Android Studio查看错误信息
  6. 百度地图android开发资料
  7. Android 通过按键旋转屏幕
  8. 2011.07.19——— android intent 传递li
  9. 高德地图自定义点聚合样式Android
  10. android 实现模拟按键