• 自定义折线图加上背景阴影效果


    最近项目中用到了折线图效果,之前没做过这种图表的功能,从网上百度一些,发现跟我要的效果不一样,于是我就开始在别人写的代码基础上进行修改,修改是一件也很辛苦的事,因为首先你要看懂别人的代码,然后才能进行一定的修改和添加代码

    下面就是我修改后的代码,夸自己一句,真的很不错

      1 /**
      2  * 备注:
      3  * 作者:王莹
      4  * 时间:2018/1/19.
      5  * ~_~想睡觉了!!
      6  * (~o~)~zZ我想睡啦~
      7  * π_π?打瞌睡
      8  */
      9 
     10 public class DrawLineView extends View {
     11     /**
     12      * 上下文
     13      */
     14     private Context mContext = null;
     15     /**
     16      * 画图区域的宽高
     17      */
     18     private float width, height;
     19     /**
     20      * 纵坐标平均每一行的高度
     21      */
     22     private float fRowHeight;
     23     /**
     24      * 横坐标平均每一列的宽带
     25      */
     26     private float fColWidth = 0;
     27     /**纵向显示个数*/
     28 //    private static final int VERTICALCOUNT = 5;
     29     /**横向显示个数*/
     30 //    private static final int HORIZONTALCOUNT = 7;
     31     /**
     32      * 固定要显示的利率
     33      */
     34 //    private static final int CONSTANT_DISPLAY_RATE = 8;
     35     /**
     36      * 横纵向字体大小单位dp
     37      */
     38     private static final int TEXTSIZE = 12;
     39     /**
     40      * 纵坐标、横坐标的字体画笔
     41      */
     42     private Paint textPaint = null;
     43     /**
     44      * 横坐标画笔
     45      */
     46     private Paint horizontalPaint = null;
     47     /**
     48      * 固定的虚线画笔
     49      */
     50     private Paint dottedLinePaint = null;
     51     /**
     52      * 画Y轴的刻度线
     53      */
     54     private Paint yLinePaint = null;
     55     /**
     56      * 画空心圆
     57      */
     58     private Paint circlePaint = null;
     59     /**
     60      * 圆的半径 单位dp
     61      */
     62     private int circleRadius = 3;
     63     /**
     64      * 折线画笔
     65      */
     66     private Paint linePaint = null;
     67     private Paint innerPaint = null;
     68     /**
     69      * 阴影画笔
     70      */
     71     private Paint shadowPaint = null;
     72     /**
     73      * 阴影走过的路径
     74      */
     75     private Path shadowPath = null;
     76 
     77     private List<Integer> yList = new ArrayList<Integer>();
     78     private List<Integer> yListtext = new ArrayList<Integer>();
     79 
     80     private List<String> xList = new ArrayList<String>();
     81     /**
     82      * Y轴的五个刻度
     83      */
     84     private List<Integer> yRateList = new ArrayList<Integer>();
     85 
     86     /**
     87      * Y轴最大值
     88      */
     89     private float maxY = 0;
     90     /**
     91      * 纵向设置的Y每一段的值
     92      */
     93     private int verticalAnnualValueY = 0;
     94     /**
     95      * 横行字体宽带
     96      */
     97     private float horizontalTextWidth = 0;
     98 
     99     /**
    100      * 横向起始位置
    101      */
    102     private float xStart = 0;
    103     private float[] xPoint;
    104     private float[] yPoint;
    105 
    106     public DrawLineView(Context context) {
    107         super(context);
    108         initWillUsed(context);
    109     }
    110 
    111     public DrawLineView(Context context, AttributeSet attrs) {
    112         super(context, attrs);
    113         initWillUsed(context);
    114     }
    115 
    116     /**
    117      * 初始化将使用到的参数
    118      */
    119     private void initWillUsed(Context context) {
    120         mContext = context;
    121 
    122         textPaint = new Paint();
    123         textPaint.setColor(Color.parseColor("#B9C7DD"));
    124         textPaint.setAntiAlias(true);
    125         textPaint.setTextSize(ValueUtils.dip2px(mContext, TEXTSIZE));
    126 
    127         horizontalPaint = new Paint();
    128         horizontalPaint.setColor(Color.parseColor("#B9C7DD"));
    129         horizontalPaint.setAntiAlias(true);
    130         horizontalPaint.setStrokeWidth(1);
    131 
    132         yLinePaint = new Paint();
    133         yLinePaint.setColor(Color.parseColor("#B9C7DD"));
    134         yLinePaint.setAntiAlias(true);
    135 
    136         dottedLinePaint = new Paint();
    137         dottedLinePaint.setStyle(Paint.Style.STROKE);
    138         dottedLinePaint.setColor(Color.parseColor("#C5D1FF"));
    139         dottedLinePaint.setAntiAlias(true);
    140 
    141         circlePaint = new Paint();
    142         circlePaint.setColor(Color.parseColor("#6789FD"));
    143         circlePaint.setStyle(Paint.Style.STROKE);
    144         circlePaint.setAntiAlias(true);
    145         circlePaint.setStrokeWidth(1);
    146 
    147         linePaint = new Paint();
    148         linePaint.setColor(Color.parseColor("#6789FD"));
    149         linePaint.setStrokeWidth(2);
    150         linePaint.setAntiAlias(true);
    151 
    152         innerPaint = new Paint();
    153         innerPaint.setColor(Color.WHITE);
    154         innerPaint.setStyle(Paint.Style.FILL);
    155         innerPaint.setAntiAlias(true);
    156 
    157 
    158     }
    159 
    160     /**
    161      * 设置将要绘制的数据
    162      */
    163     public void setData(List<String> xValuesList, List<Integer> yValuesList, float currMaxY) {
    164         this.xList = xValuesList;
    165         this.yList = yValuesList;
    166         yListtext.clear();
    167         yRateList.clear();
    168         for (int i = 0; i < yList.size(); i++) {
    169             yListtext.add(yList.get(i));
    170         }
    171         xPoint = new float[xList.size()];
    172         yPoint = new float[xList.size()];
    173 
    174         if (currMaxY / yList.size() == currMaxY % yList.size()) {
    175             verticalAnnualValueY = (int) currMaxY / yList.size();
    176         } else {
    177             verticalAnnualValueY = (int) currMaxY / yList.size() + 1;
    178         }
    179 
    180         maxY = yList.size() * verticalAnnualValueY;
    181 
    182 
    183         for (int i = yListtext.size(); i >= 1; i--) {
    184             yRateList.add(verticalAnnualValueY * i);
    185         }
    186         setWillNotDraw(false);
    187     }
    188 
    189     @Override
    190     protected void onDraw(Canvas canvas) {
    191         super.onDraw(canvas);
    192         width = getWidth();
    193         height = getHeight();
    194         fRowHeight = (float) height / (yList.size()+1);
    195         xStart = 0;
    196         fColWidth = 0;
    197         shadowPaint = new Paint();
    198         shadowPaint.setAntiAlias(true);
    199         shadowPath = new Path();
    200         drawVertical(canvas);
    201 
    202         drawHorizontal(canvas);
    203 
    204 //        drawDottedLine(canvas);
    205 
    206         drawYLine(canvas);
    207 
    208         drawLine(canvas);
    209 
    210         drawCircle(canvas);
    211     }
    212 
    213     /**
    214      * 画纵向数据
    215      */
    216     private void drawVertical(Canvas canvas) {
    217         Integer temp=0;
    218         for (int i = 0; i < yRateList.size()-1; i++) {
    219             for (int j = i + 1; j < yRateList.size(); j++) {
    220                 if (yRateList.get(i)< yRateList.get(j)) { // 交换两数的位置
    221                     temp = yRateList.get(i);
    222                     yRateList.set(i,yRateList.get(j));
    223 //                    yRateList.get(i) = yRateList.get(j);
    224                     yRateList.set(j,temp);
    225 //                    yRateList.get(j) = temp;
    226                 }
    227             }
    228         }
    229 //        //降序
    230 //        Collections.reverse(yRateList);
    231         for (int i = 0; i < yRateList.size(); i++) {
    232             Integer verticalContent = yRateList.get(i);
    233             canvas.drawText(verticalContent + "", 0, i * fRowHeight + ValueUtils.dip2px(mContext, TEXTSIZE), textPaint);
    234 
    235             if (xStart < textPaint.measureText(verticalContent + "")) {
    236                 xStart = textPaint.measureText(verticalContent + "");
    237             }
    238         }
    239         xStart = xStart * 3 / 2;
    240     }
    241 
    242     /**
    243      * 画横向数据
    244      */
    245     private void drawHorizontal(Canvas canvas) {
    246         for (int i = 0; i < xList.size(); i++) {
    247             String horizontalContent = xList.get(i);
    248             horizontalTextWidth = textPaint.measureText(horizontalContent);
    249             if (fColWidth == 0) {
    250                 fColWidth = (width - xStart - horizontalTextWidth) / (xList.size() - 1);
    251             }
    252             canvas.drawText(horizontalContent, xStart + i * fColWidth - horizontalTextWidth / 2, yList.size() * fRowHeight + ValueUtils.dip2px(mContext, TEXTSIZE + 10), textPaint);
    253 
    254 //            if (i == xList.size() - 1) {
    255 //                canvas.drawLine(xStart, yList.size() * fRowHeight, fColWidth * i + horizontalTextWidth, yList.size() * fRowHeight, horizontalPaint);
    256 //            }
    257         }
    258     }
    259 
    260 //    /**
    261 //     * 画固定8%的虚线
    262 //     */
    263 //    private void drawDottedLine(Canvas canvas) {
    264 //        float dottedWidth = (maxY - CONSTANT_DISPLAY_RATE) * yList.size() * fRowHeight / maxY + ValueUtils.dip2px(mContext, TEXTSIZE);
    265 //        Path path = new Path();
    266 //        path.moveTo(xStart, dottedWidth);
    267 //        path.lineTo(fColWidth * (xList.size() - 1) + horizontalTextWidth, dottedWidth);
    268 //        PathEffect effects = new DashPathEffect(new float[]{4, 4, 4, 4}, 4f);
    269 //        dottedLinePaint.setPathEffect(effects);
    270 //        canvas.drawPath(path, dottedLinePaint);
    271 //    }
    272 
    273     /**
    274      * 画Y轴的刻度线
    275      */
    276     private void drawYLine(Canvas canvas) {
    277         for (int i = 0; i < yList.size(); i++) {
    278             canvas.drawLine(xStart, i * fRowHeight + ValueUtils.dip2px(mContext, TEXTSIZE), fColWidth * (xList.size()), i * fRowHeight + ValueUtils.dip2px(mContext, TEXTSIZE), yLinePaint);
    279         }
    280     }
    281 
    282     /**
    283      * 画空心圆
    284      */
    285     private void drawCircle(Canvas canvas) {
    286         for (int i = 0; i < xList.size(); i++) {
    287             canvas.drawCircle(xPoint[i], yPoint[i], ValueUtils.dip2px(mContext, circleRadius), circlePaint);
    288 
    289             float innerValue = ValueUtils.dip2px(mContext, circleRadius) - 1.6F;
    290 
    291             innerPaint.setColor(Color.WHITE);
    292             innerPaint.setStyle(Paint.Style.FILL);
    293             innerPaint.setAntiAlias(true);
    294             canvas.drawCircle(xPoint[i], yPoint[i], innerValue, innerPaint);
    295         }
    296     }
    297 
    298     /**
    299      * 画折线 和 阴影
    300      */
    301     private void drawLine(Canvas canvas) {
    302         int maxHeightPoint = 0;//记录最高的点
    303         float maxHeight = 0;
    304         for (int i = 0; i < xList.size(); i++) {
    305             xPoint[i] = xStart + i * fColWidth;
    306 
    307             if (maxHeight < yList.get(i)) {
    308                 maxHeight = yList.get(i);
    309                 maxHeightPoint = i;
    310             }
    311             yPoint[i] = (maxY - yList.get(i)) / maxY * yList.size() * fRowHeight + ValueUtils.dip2px(mContext, TEXTSIZE);
    312 
    313             if (i > 0) {
    314                 canvas.drawLine(xPoint[i - 1], yPoint[i - 1], xPoint[i], yPoint[i], linePaint);
    315                 if (i == 1) {
    316                     shadowPath.moveTo(xPoint[i - 1], yPoint[i - 1]);
    317                 }
    318                 shadowPath.lineTo(xPoint[i], yPoint[i]);
    319             }
    320         }
    321         shadowPath.lineTo(xPoint[xList.size() - 1], yList.size() * fRowHeight);
    322         shadowPath.lineTo(xPoint[0], yList.size() * fRowHeight);
    323         shadowPath.close();
    324         Shader lShader = new LinearGradient(0, yPoint[maxHeightPoint], 0, yList.size() * fRowHeight, Color.parseColor("#BFC5D1FF"), Color.parseColor("#BFFDFDFF"), Shader.TileMode.REPEAT);
    325         shadowPaint.setShader(lShader);
    326         canvas.drawPath(shadowPath, shadowPaint);
    327     }
    328 }

    用来也很简单呀!

        <com.egojit.android.sops.views.Chart.DrawLineView
                    android:id="@+id/cv_chartView"
                    android:layout_width="match_parent"
                    android:layout_height="300dp"
                    android:visibility="gone"
                    >
    
                </com.egojit.android.sops.views.Chart.DrawLineView>
        private void initLineDatas() {
    //        cv_chartView.setShowNum(listarray.size());
            maxlist = new ArrayList<>();
            for (int i = 0; i < listarray.size(); i++) {
                maxlist.add(listarray.getJSONObject(i).getFloatValue("sq"));
                ydatas.add(listarray.getJSONObject(i).getInteger("sq"));
            }
    
            float maxValueY = Collections.max(maxlist);
            cv_chartView.setData(xdata, ydatas, maxValueY);
            cv_chartView.postInvalidate();
        }

    不过注意的是,如果你需要切换数据或者改其他数据,肯定都要吧之前数据清掉的哦!希望可以帮到其他小伙伴啦!

    把效果图也发给大家吧!

    跟效果图不一样的是我加了圆点

  • 相关阅读:
    Customizing the Test Runner
    Creating Custom Shadows ——创建自定义shadow
    Extending Robolectric
    Driving the Activity Lifecycle
    Configuring Robolectric
    Writing Your First Test
    Getting Started
    Robolectric Test-Drive Your Android Code
    为知笔记 | 为知笔记 Markdown 新手指南
    LeetCode_238_Product of Array Except Self
  • 原文地址:https://www.cnblogs.com/wangying222/p/8397897.html
Copyright © 2020-2023  润新知