服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android实现折线走势图

Android实现折线走势图

2022-11-08 14:41姜丝儿jlq Android

这篇文章主要为大家详细介绍了Android实现折线走势图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android折线走势图的具体代码,供大家参考,具体内容如下

先来看看效果图

Android实现折线走势图

可以根据球的数量动态的改变自己的球半径,以及线宽

Android实现折线走势图

代码实现也是超级简单

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//获取自定义属性
private void obtainStyledAttrs(AttributeSet attrs) {
  TypedArray typedArray = getContext().obtainStyledAttributes(attrs,R.styleable.High_LowChartView);
  mTextSize = (int)typedArray.getDimension(R.styleable.High_LowChartView_hl_chart_textsize,mTextSize);
  mTextColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_textcolor,mTextColor);
  if (typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text)!=null){
   mHighText = typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text);
  }
  if(typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text)!=null){
   mLowText = typedArray.getString(R.styleable.High_LowChartView_hl_hchart_text);
  }
  mHighPointColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_high_pointcolor,mHighPointColor);
  mLowPointColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_low_pointcolor,mLowPointColor);
  mMainLineColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_mianlinecolor,mMainLineColor);
  mChartLineColor = typedArray.getColor(R.styleable.High_LowChartView_hl_chart_chartlinecolor,mChartLineColor);
  mChartDistance = (int) typedArray.getDimension(R.styleable.High_LowChartView_hl_chart_distance,mChartDistance);
 
  init();
  typedArray.recycle();
 }
 
//重写onMeasure
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  int width = MeasureSpec.getSize(widthMeasureSpec);
  int height = measureHeight(heightMeasureSpec);
  setMeasuredDimension(width,height);
 
 }
//计算view需要的高度
 private int measureHeight(int heightMeasureSpec) {
  int result = 0;
  int mode = MeasureSpec.getMode(heightMeasureSpec);
  int size = MeasureSpec.getSize(heightMeasureSpec);
  if(mode == MeasureSpec.EXACTLY){//如果给了具体值则直接用
   result=size;
  }else {
  //否则高度等于字高与球直径的最大值
   textHeight = (mPaint.descent()-mPaint.ascent());
   float halfHeight = Math.max(textHeight, mPointMaxHeight) / 2;
   result = (int) (halfHeight+mChartDistance);
   //如果模式为AT_MOST即:测量高度不能超过父类给定的高度则取测量结果与size的最小值
   if(mode==MeasureSpec.AT_MOST){
    result = Math.min(result,size);
   }
  }
  return result;
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if(!initMeasure()) return;
  canvas.save();
  //1先画两条主线
  mPaint.setColor(mMainLineColor);
  mPaint.setStrokeWidth(mainLineHeight);
 
  //high Line
  canvas.drawLine(textWidth+DEFAULT_OFFSETTING,mainLinePosition,w,mainLinePosition,mPaint);
  //low Line
  canvas.drawLine(textWidth+DEFAULT_OFFSETTING,mainLinePosition+mChartDistance,w,mainLinePosition+mChartDistance,mPaint);
 
  //2再画文字
  mPaint.setColor(mTextColor);
  mPaint.setTextAlign(Paint.Align.LEFT);
  Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
  RectF rt1=new RectF(0,mainLinePosition-textHeight/2,w,mainLinePosition+textHeight/2);
  int baseline = (int) ((rt1.bottom + rt1.top - fontMetrics.bottom - fontMetrics.top) / 2);
  canvas.drawText(mHighText,0,baseline,mPaint);
  canvas.drawText(mLowText,0,baseline+mChartDistance,mPaint);
 
  //3初始化小球圆心
  canvas.translate(textWidth+DEFAULT_OFFSETTING,0);
 
  for (int i=0;i<mPointNum;i++){
   //high point
   if (mList.get(i).isHighPoint){
//    mPaint.setColor(mHighPointColor);
//    canvas.drawCircle((pointHeight/2+offsetX)+i*(pointHeight+offsetX), mainLinePosition, pointHeight/2, mPaint);
    //存入小球的圆心坐标
    mList.get(i).setXY((pointHeight/2+offsetX)+i*(pointHeight+offsetX),mainLinePosition);
   }else {
    //low point
//    mPaint.setColor(mLowPointColor);
//    canvas.drawCircle((pointHeight/2+offsetX)+i*(pointHeight+offsetX), mainLinePosition+mChartDistance, pointHeight/2, mPaint);
    mList.get(i).setXY((pointHeight/2+offsetX)+i*(pointHeight+offsetX),mainLinePosition+mChartDistance);
   }
  }
  //4连接小球
  if(mList.size()>=2){
   mPaint.setColor(mChartLineColor);
   mPaint.setStrokeWidth(chartLineWidth);
   for (int i=0;i<mPointNum-1;i++){
    canvas.drawLine(mList.get(i).cx,mList.get(i).cy,mList.get(i+1).cx,mList.get(i+1).cy,mPaint);
   }
  }
  //5绘制小球(为了不让线遮盖小球)
  for (int i=0;i<mPointNum;i++){
   //high point
   if (mList.get(i).isHighPoint){
    mPaint.setColor(mHighPointColor);
    //low point
   }else {
    mPaint.setColor(mLowPointColor);
   }
   canvas.drawCircle(mList.get(i).cx, mList.get(i).cy, pointHeight/2, mPaint);
  }
  canvas.restore();
 }
 
 /**
  * 根据小球数量去动态测量一些属性
  * @return
  */
 private boolean initMeasure() {
  //根据传进来的point数量计算小点的大小,MainLine的线宽,折线的线宽
   /* 如果小球数量在1-10个,主线高度为3dip
   * 如果小球数量在10-20个,主线高度设置为2dip
   * 如果小球数量超过20个,主线高度设置为1dp
   */
  mPointNum=mList.size();
//  if(mPointNum==0) return false;
  if(10>mPointNum){
   mainLineHeight=dp2px(3);
  }else if(10<=mPointNum&&20>mPointNum){
   mainLineHeight = dp2px(2);
  }else {
   mainLineHeight = dp2px(1);
  }
 
  //主线长度等于总宽度-(文字宽度+30px)
  textWidth=Math.max(mPaint.measureText(mHighText),mPaint.measureText(mLowText));
  mainLineWidth = (int) (w-(textWidth+DEFAULT_OFFSETTING));
 
  /*小球直径应该由主线长度与小球数量决定*/
  //理想直径
  float ideaDia = mainLineWidth / (mPointNum + (mPointNum + 1));
  //小球直径不能大于最大直径
  if(ideaDia>mPointMaxHeight){
//   Log.i("TTT","ideaDia>mPointMaxHeight");
   pointHeight = mPointMaxHeight;
   offsetX=(mainLineWidth-mPointNum*pointHeight)/(mPointNum+1);
   //(极端情况)如果小球直径小于线高,为小球直径+2px
  }else if(ideaDia<=mainLineHeight){
//   Log.i("TTT","ideaDia<=mPointMaxHeight");
   pointHeight = mainLineHeight+2;
   offsetX=(mainLineWidth-mPointNum*pointHeight)/(mPointNum+1);
  }else {
//   Log.i("TTT"," pointHeight=offsetX=ideaDia");
   pointHeight=offsetX=ideaDia;
  }
  //主线位置
  mainLinePosition = (h-mChartDistance)/2;
  //折线宽度
  chartLineWidth = mainLineHeight/2;
  return true;
 }
 
//刷新小球集合
 public void setPointList(List<AiyingPoint> list){
  if (list==null&&list.size()==0) return;
  mList.clear();
  if (list.size()>150) {
   mList.addAll(list.subList(0,150));
  } else {
   mList.addAll(list);
  }
  invalidate();
 }

使用示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<com.android.view.High_LowChartView
   android:id="@+id/hl_chart"
   android:layout_below="@+id/tv_state"
   android:layout_marginLeft="15dp"
   android:layout_marginRight="15dp"
   android:layout_width="match_parent"
   android:layout_height="70dp"
   app:hl_chart_mianlinecolor="#CDCDCD"
   app:hl_chart_distance="55dp"
   app:hl_chart_low_pointcolor="#999999"
   app:hl_chart_high_pointcolor="#F70919"
   app:hl_chart_textsize="13sp"
   app:hl_chart_textcolor="#2f2f2f"
   app:hl_chart_chartlinecolor="#999999"
 />

好了这样折线图就绘制完成了,是不是很简单呢?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_23347751/article/details/69055069

延伸 · 阅读

精彩推荐