zoukankan      html  css  js  c++  java
  • 环形图 自定义(一)

    需求:自定义环形图(饼图),实现2项数据配比显示;

    效果图:

    实现分析:

    1.目录结构:

    代码实现:

    1. color.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <!-- 饼图 -->
        <color name="pie_progress_bank">#fd8f8b</color>
        <color name="pie_progress_fund">#2999f9</color>
        <color name="text_tag_bg">#aaaaaa</color>
        <color name="text_progress_bg">#fb4b45</color>
        <color name="text_term_bg">#aaaaaa</color>
    
    </resources>

    2. fragment_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.jjc.demo.MainActivity$PlaceholderFragment" >
    
        <com.jjc.demo.RingView
            android:id="@+id/ringview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </RelativeLayout>

    3. RingView.java

    package com.jjc.demo;
    
    import java.math.BigDecimal;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.graphics.Paint.Style;
    import android.util.AttributeSet;
    import android.view.View;
    
    /**
     * 当前环形图实现原理,先画一个完整环形,然后再画一部分环形,两者叠加,显示两种不同的配比;
     * @author ThinkPad
     *
     */
    public class RingView extends View{
        
        /** 当前进度 */
        private int progress;
        /** 总进度 */
        private int max;
        
        private Paint paint;
        private RectF oval;
    
        private int width;
        private int height;
    
        private String term = "";
    
        /** 半径 */
        private float radius;
    
        /** 画笔宽度 */
        private float paintWidth;
    
        /** 组合字体 */
    //    private float tagTextSize;
    
        /** 配比字体 */
        private float progressTextSize;
        
    //    private float tagTextSize;
    
        /** 期限字体 */
    //    private float termTextSize;
    
        private double rate;
    
    
        /**
         * 设置总数
         * @param max
         */
        public void setMax(int max) {
            this.max = max;
        }
    
        public void setPaintWidth(float paintWidth) {
            this.paintWidth = paintWidth;
        }
    
        /**
         * 设置进度
         * @param progress
         */
        public void setProgress(int progress) {
            this.progress = progress;
            invalidate();
        }
    
        /**
         * 设置收益率
         * @param rate
         */
        public void setRate(double rate) {
            this.rate = round(rate, 2, 4);
        }
    
        public void setTerm(String term) {
            this.term = term;
    
        }
    
        
    
        public RingView(Context context, AttributeSet attrs) {
            super(context, attrs);
            paint = new Paint();
            oval = new RectF();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            height = canvas.getHeight();
            width = canvas.getWidth();
            
            initRadius();
            initPaint();
            initDebugLine(canvas ,false);
            initBankPaint(canvas);
            initFundPaint(canvas);
            
            initDescrip(canvas);
        }
        
        /**
         * 测试文字是否居中,标尺线
         */
        private void initDebugLine(Canvas canvas ,boolean isDebug) {
            
            if(isDebug){
                //竖线
                paint.setColor(Color.BLACK); canvas.drawLine(width/2, 0, width/2, height, paint);
                //横线 
                paint.setColor(Color.GRAY); canvas.drawLine(0, height/2, width, height/2, paint);
            }
        }
    
        /**
         * 比较高度和宽度,然后取短的作为圆环的半径
         */
        private void initRadius() {
            if (width > height) {
                radius = (float) (height * 0.4);
            } else {
                radius = (float) (width * 0.4);
            }
        }
    
        private void initPaint() {
            if(paintWidth == 0){
                paintWidth = radius/10;
            }
            
            paint.setAntiAlias(true);// 设置是否抗锯齿
            paint.setFlags(Paint.ANTI_ALIAS_FLAG);// 帮助消除锯齿
        }
    
        private void initBankPaint(Canvas canvas) {
            paint.setColor(getResources().getColor(R.color.pie_progress_bank));// 设置银行理财画笔
            
            /** 银行理财标注 */
            // 设置样式-填充   
            paint.setStyle(Style.FILL);   
            // 绘制一个矩形   
            canvas.drawRect(new Rect(10, height-35, 22, height-15), paint); 
            paint.setTextSize((float) (radius/5.5));// 设置标注文字的大小
            canvas.drawText("银行理财", 35, height-18, paint);
            
            /** 银行理财的饼图  */
            paint.setStrokeWidth(paintWidth);// 设置画笔宽度
            paint.setStyle(Style.STROKE);// 设置中空的样式
            canvas.drawCircle(width / 2, height / 2, radius, paint);
        }
        
        private void initFundPaint(Canvas canvas) {
            paint.setColor(getResources().getColor(R.color.pie_progress_fund));// 设置货币基金画笔
            
            /** 货币基金标注 */
            // 设置样式-填充   
            paint.setStyle(Style.FILL);   
            // 绘制一个矩形   
            canvas.drawRect(new Rect(10, height-65, 22, height-45), paint); 
            paint.setTextSize((float) (radius/5.5));// 设置标注文字的大小
            canvas.drawText("货币基金", 35, height-48, paint);
            
            /** 货币基金的饼图  */
            paint.setStrokeWidth(paintWidth);// 设置画笔宽度
            paint.setStyle(Style.STROKE);// 设置中空的样式
            oval.set((width / 2 - radius), (height / 2 - radius),
                    (width / 2 + radius), (height / 2 + radius));
            canvas.drawArc(oval, -90, ((float) progress / max) * 360, false, paint);// 画圆弧,第二个参数为:起始角度,第三个为跨的角度,第四个为true的时候是实心,false的时候为空心
        }
        
        private void initDescrip(Canvas canvas) {
            paint.reset();// 将画笔重置
            paint.setStrokeWidth(3);// 再次设置画笔的宽度
    
            progressTextSize = (float) (radius / 2);
    
            paint.setTextSize((float) (radius / 7));// 设置标记文字的大小
            paint.setColor(getResources().getColor(R.color.text_tag_bg));// 设置画笔颜色
            canvas.drawText("组合收益率", (float) (width / 2 - radius / 2.8),
                    (float) (height / 2 - progressTextSize * 0.5), paint);
    
            paint.setTextSize((float) (radius / 7));// 设置期限文字的大小
            paint.setColor(getResources().getColor(R.color.text_term_bg));// 设置画笔颜色
            canvas.drawText(term, (float) (width / 2 - radius / 4.5),
                    (float) (height / 2 + progressTextSize * 0.7), paint);
    
            /** 配比数 */
            paint.setTextSize(progressTextSize);// 设置进度文字的大小
            paint.setColor(getResources().getColor(R.color.text_progress_bg));// 设置画笔颜色
    
            canvas.drawText(rate+"",
                    (float) (width / 2 - progressTextSize * 1.1),
                    (float) (height / 2 + progressTextSize / 2.5), paint);
            
            paint.setTextSize((float) (radius / 5));// 设置百分号的大小
            canvas.drawText("%",
                    (float) (width / 2 + progressTextSize * 0.9),
                    (float) (height / 2 + progressTextSize / 2.5), paint);
        }
    
        /**
         * 对double数据进行取精度.
         * <p>
         * For example: <br>
         * double value = 100.345678; <br>
         * double ret = round(value,4,BigDecimal.ROUND_HALF_UP); <br>
         * ret为100.3457 <br>
         * 
         * @param value
         *            double数据.
         * @param scale
         *            精度位数(保留的小数位数).
         * @param roundingMode
         *            精度取值方式.
         * @return 精度计算后的数据.
         */
        private double round(double value, int scale, int roundingMode) {
            BigDecimal bd = new BigDecimal(value);
            bd = bd.setScale(scale, roundingMode);
            double d = bd.doubleValue();
            bd = null;
            return d;
        }
        
    }

    4.MainActivity.java

    package com.jjc.demo;
    
    import android.support.v7.app.ActionBarActivity;
    import android.support.v4.app.Fragment;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class MainActivity extends ActionBarActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (savedInstanceState == null) {
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.container, new PlaceholderFragment()).commit();
            }
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    
        /**
         * A placeholder fragment containing a simple view.
         */
        public static class PlaceholderFragment extends Fragment {
    
            private View rootView;
            private RingView ringView;
    
            public PlaceholderFragment() {
            }
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                rootView = inflater.inflate(R.layout.fragment_main, container, false);
                return rootView;
            }
            
            @Override
            public void onActivityCreated(Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
                initView();
            }
    
            private void initView() {
                ringView = (RingView) rootView.findViewById(R.id.ringview);
                ringView.setMax(100);
                ringView.setRate(5.43);
                ringView.setTerm("六个月");
                ringView.setProgress(40);
            }
            
        }
    
    }

    代码:http://pan.baidu.com/s/1eQzk5SQ

  • 相关阅读:
    实验5 Spark SQL 编程初级实践
    豆瓣基础架构
    淘宝数据魔方技术架构解析
    质量属性的六个常见属性场景--淘宝网
    Win10家庭版WindowsUpdate属性为灰色
    豆瓣的基础架构
    京东618实践:一元抢宝系统的数据库架构优化
    FunData — 电竞大数据系统架构演进
    Ubuntu14.0使用gparted调整分区大小
    二阶段开发冲刺一
  • 原文地址:https://www.cnblogs.com/sishuiliuyun/p/3949575.html
Copyright © 2011-2022 走看看