Android自定義View--自己擼一個柱狀圖也沒那么難


緒論

*轉眼間,2016伴隨着互聯網寒冬和帝都的霧霾馬上就過去了,不知道大家今年一整年過得怎么樣?最近票圈被各個城市的霧霾刷屏, 
內心難免會動盪,慶幸自己早出來一年,也擔憂着自己的未來的職業規划。無所謂了,既然選擇了這個行業,我覺得大家就應該堅持下去,路是自己走的,及時再寒冬,只要你足夠優秀,足夠努力,相信你最后還是會找到自己滿意的工作的。最后還要感謝今年博客之星大家對我的投票支持,非常感謝。不多說了,今天的主題是它–對,自定義View柱狀圖。 
先來說說我最近在做什么吧?好久沒有寫博客了,最近手里有兩個項目,閑的時候一直在忙着做項目,也封裝了屬於自己的一套Library,抽下來我會把它分享出來的。公司的項目也一直在忙,今天的柱狀圖就是公司的項目所用到的。先來看一下效果吧


*

這里寫圖片描述

背景

需求剛下來的時候我去網上找了一些開源的項目比如: 
MpChart 
hellocharts-android 
AndroidCharts 
等等有好多,但是最后為什么我選擇了自定義,一來是這些開源庫都很“重”,好多都用不到;二來很少有雙條的柱狀圖;三來也想提高一下自己,仔細研究一下發現也並沒有那么難。感興趣的話可以去研究一下開源的那些圖表,不過我曾經想過在上面的那幾個基礎上去修改,發現很難,所幸自己定義吧。


具體實現

可以看到,今天的柱狀圖分為三類:雙條豎向柱狀圖、單條豎向柱狀圖以及單條橫向柱狀圖,其實原理都是一樣的,下面我們具體看一下怎么實現,怎么去畫一個這樣的柱狀圖。

雙條豎向

我們可以看到這個柱狀圖主要包括下面幾個方面:

  1. 雙條柱狀圖
  2. 橫坐標月份
  3. 點擊tips顯示具體數值
  4. 灰色陰影(圖上沒有顯示具體看代碼)
  5. 柱狀圖漸變、圓角、點擊變色

好了上面五點就是需求和UI所提出來的所有東西,我們開始着手去“畫”吧。


1.首先我們定義一些資源style供使用

包括 
leftColor 左側柱狀圖頂部顏色 
leftColorBottom 左側柱狀圖底部顏色 
rightColor 右側柱狀圖頂部顏色 
rightColorBottom 右側柱狀圖底部顏色 
selectRightColor 左側點擊選中顏色 
selectRightColor 右側點擊選中顏色 
xyColor 橫軸字體顏色

底部和頂部顏色是用於漸變用的

<declare-styleable name="MyChartView"> <attr name="leftColor" format="color"></attr> <attr name="leftColorBottom" format="color"></attr> <attr name="selectLeftColor" format="color"></attr> <attr name="rightColor" format="color"></attr> <attr name="rightColorBottom" format="color"></attr> <attr name="selectRightColor" format="color"></attr> <attr name="xyColor" format="color"></attr> </declare-styleable>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.接下來我們看具體代碼,注釋寫的很詳細了,仔細看:

  • 初始化屬性、畫筆、所用的size等
  • 測量計算高寬度等
  • 畫坐標軸、畫月份、畫柱狀圖、畫陰影
  • 柱狀圖漸變以及點擊變色
  • touch點擊事件判斷點擊所屬哪個月份,接口回調給activity顯示具體月份數值

    注意:onWindowVisibilityChanged這個方法(當屏幕焦點變化時重新側向起始位置,必須重寫次方法,否則當焦點變化時柱狀圖會跑到屏幕外面)
    

下面主要說一下繪制部分吧

OnDraw()部分

我們將每次onTouch的條的索引放到selectIndexRoles數組中,然后當這個數組包含該繪制的柱狀圖的索引是我們設置不用顏色以及不設置漸變; 
同時我們給每兩個雙條之間的的空白處繪制成陰影; 
最后drawRoundRect()就繪制了一個圓角的矩形。

//畫柱狀圖 for (int i = 0; i < list.size(); i++) { int size = mHeight / 120; if (selectIndexRoles.contains(i)) { //偶數 mChartPaint.setShader(null); if (i % 2 == 0) { mChartPaint.setColor(selectLeftColor); } else { mChartPaint.setColor(selectRightColor); } } else { //偶數 if (i % 2 == 0) { LinearGradient lg = new LinearGradient(mChartWidth, mChartWidth + mSize, mHeight - 100, (float) (mHeight - 100 - list.get(i) * size), lefrColorBottom, leftColor, Shader.TileMode.MIRROR); mChartPaint.setShader(lg); } else { LinearGradient lg = new LinearGradient(mChartWidth, mChartWidth + mSize, mHeight - 100, (float) (mHeight - 100 - list.get(i) * size), rightColorBottom, rightColor, Shader.TileMode.MIRROR); mChartPaint.setShader(lg); } } mChartPaint.setStyle(Paint.Style.FILL); //畫陰影 if (i == number * 2 || i == number * 2 + 1) { mShadowPaint.setColor(Color.BLUE); } else { mShadowPaint.setColor(Color.WHITE); } //畫柱狀圖 RectF rectF = new RectF(); rectF.left = mChartWidth; rectF.right = mChartWidth + mSize; rectF.bottom = mHeight - 100; rectF.top = (float) (mHeight - 100 - list.get(i) * size); canvas.drawRoundRect(rectF, 10, 10, mChartPaint); //canvas.drawRect(mChartWidth, mHeight - 100 - list.get(i) * size, mChartWidth + mSize, mHeight - 100, mChartPaint) // ;// 長方形 mChartWidth += (i % 2 == 0) ? (3 + getWidth() / 39) : (getWidth() / 13 - 3 - mSize); }
  • 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
  • 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
全部代碼
package com.hankkin.mycartdemo.chatview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import com.hankkin.mycartdemo.R; import java.util.ArrayList; import java.util.List; /** * Created by Hankkin on 2016/12/10. */ public class MyChartView extends View { private int leftColor;//雙柱左側 private int rightColor;//雙柱右側 private int lineColor;//橫軸線 private int selectLeftColor;//點擊選中左側 private int selectRightColor;//點擊選中右側 private int lefrColorBottom;//左側底部 private int rightColorBottom;//右側底部 private Paint mPaint, mChartPaint, mShadowPaint;//橫軸畫筆、柱狀圖畫筆、陰影畫筆 private int mWidth, mHeight, mStartWidth, mChartWidth, mSize;//屏幕寬度高度、柱狀圖起始位置、柱狀圖寬度 private Rect mBound; private List<Float> list = new ArrayList<>();//柱狀圖高度占比 private Rect rect;//柱狀圖矩形 private getNumberListener listener;//點擊接口 private int number = 1000;//柱狀圖最大值 private int selectIndex = -1;//點擊選中柱狀圖索引 private List<Integer> selectIndexRoles = new ArrayList<>(); public void setList(List<Float> list) { this.list = list; mSize = getWidth() / 39; mStartWidth = getWidth() / 13; mChartWidth = getWidth() / 13 - mSize - 3; invalidate(); } public void setListener(getNumberListener listener) { this.listener = listener; } public MyChartView(Context context) { this(context, null); } public MyChartView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyChartView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //獲取我們自定義的樣式屬性 TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyChartView, defStyleAttr, 0); int n = array.getIndexCount(); for (int i = 0; i < n; i++) { int attr = array.getIndex(i); switch (attr) { case R.styleable.MyChartView_leftColor: // 默認顏色設置為黑色 leftColor = array.getColor(attr, Color.BLACK); break; case R.styleable.MyChartView_selectLeftColor: // 默認顏色設置為黑色 selectLeftColor = array.getColor(attr, Color.BLACK); break; case R.styleable.MyChartView_rightColor: rightColor = array.getColor(attr, Color.BLACK); break; case R.styleable.MyChartView_selectRightColor: selectRightColor = array.getColor(attr, Color.BLACK); break; case R.styleable.MyChartView_xyColor: lineColor = array.getColor(attr, Color.BLACK); break; case R.styleable.MyChartView_leftColorBottom: lefrColorBottom = array.getColor(attr, Color.BLACK); break; case R.styleable.MyChartView_rightColorBottom: rightColorBottom = array.getColor(attr, Color.BLACK); break; } } array.recycle(); init(); } //初始化畫筆 private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mBound = new Rect(); mChartPaint = new Paint(); mChartPaint.setAntiAlias(true); mShadowPaint = new Paint(); mShadowPaint.setAntiAlias(true); mShadowPaint.setColor(Color.WHITE); } //測量高寬度 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width; int height; int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = widthSize * 1 / 2; } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = heightSize * 1 / 2; } setMeasuredDimension(width, height); } //計算高度寬度 @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mWidth = getWidth(); mHeight = getHeight(); mStartWidth = getWidth() / 13; mSize = getWidth() / 39; mChartWidth = getWidth() / 13 - mSize; } //重寫onDraw繪制 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(lineColor); //畫坐標軸 //canvas.drawLine(0, mHeight - 100, mWidth, mHeight - 100, mPaint); for (int i = 0; i < 12; i++) { //畫刻度線 //canvas.drawLine(mStartWidth, mHeight - 100, mStartWidth, mHeight - 80, mPaint); //畫數字 mPaint.setTextSize(35); mPaint.setTextAlign(Paint.Align.CENTER); mPaint.getTextBounds(String.valueOf(i + 1) + "", 0, String.valueOf(i).length(), mBound); canvas.drawText(String.valueOf(i + 1) + "月", mStartWidth - mBound.width() * 1 / 2, mHeight - 60 + mBound.height() * 1 / 2, mPaint); mStartWidth += getWidth() / 13; } //畫柱狀圖 for (int i = 0; i < list.size(); i++) { int size = mHeight / 120; if (selectIndexRoles.contains(i)) { //偶數 mChartPaint.setShader(null); if (i % 2 == 0) { mChartPaint.setColor(selectLeftColor); } else { mChartPaint.setColor(selectRightColor); } } else { //偶數 if (i % 2 == 0) { LinearGradient lg = new LinearGradient(mChartWidth, mChartWidth + mSize, mHeight - 100, (float) (mHeight - 100 - list.get(i) * size), lefrColorBottom, leftColor, Shader.TileMode.MIRROR); mChartPaint.setShader(lg); } else { LinearGradient lg = new LinearGradient(mChartWidth, mChartWidth + mSize, mHeight - 100, (float) (mHeight - 100 - list.get(i) * size), rightColorBottom, rightColor, Shader.TileMode.MIRROR); mChartPaint.setShader(lg); } } mChartPaint.setStyle(Paint.Style.FILL); //畫陰影 if (i == number * 2 || i == number * 2 + 1) { mShadowPaint.setColor(Color.BLUE); } else { mShadowPaint.setColor(Color.WHITE); } //畫柱狀圖 RectF rectF = new RectF(); rectF.left = mChartWidth; rectF.right = mChartWidth + mSize; rectF.bottom = mHeight - 100; rectF.top = (float) (mHeight - 100 - list.get(i) * size); canvas.drawRoundRect(rectF, 10, 10, mChartPaint); //canvas.drawRect(mChartWidth, mHeight - 100 - list.get(i) * size, mChartWidth + mSize, mHeight - 100, mChartPaint) // ;// 長方形 mChartWidth += (i % 2 == 0) ? (3 + getWidth() / 39) : (getWidth() / 13 - 3 - mSize); } } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); if (hasWindowFocus) { } } /** * 注意: * 當屏幕焦點變化時重新側向起始位置,必須重寫次方法,否則當焦點變化時柱狀圖會跑到屏幕外面 */ @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); if (visibility == VISIBLE) { mSize = getWidth() / 39; mStartWidth = getWidth() / 13; mChartWidth = getWidth() / 13 - mSize - 3; } } /** * 柱狀圖touch事件 * 獲取觸摸位置計算屬於哪個月份的 * @param ev * @return */ @Override public boolean onTouchEvent(MotionEvent ev) { int x = (int) ev.getX(); int y = (int) ev.getY(); int left = 0; int top = 0; int right = mWidth / 12; int bottom = mHeight - 100; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: for (int i = 0; i < 12; i++) { rect = new Rect(left, top, right, bottom); left += mWidth / 12; right += mWidth / 12; if (rect.contains(x, y)) { listener.getNumber(i, x, y); number = i; selectIndex = i; selectIndexRoles.clear(); ; selectIndexRoles.add(selectIndex * 2 + 1); selectIndexRoles.add(selectIndex * 2); invalidate(); } } break; case MotionEvent.ACTION_UP: break; } return true; } public interface getNumberListener { void getNumber(int number, int x, int y); } public int getLeftColor() { return leftColor; } public void setLeftColor(int leftColor) { this.leftColor = leftColor; } public int getRightColor() { return rightColor; } public void setRightColor(int rightColor) { this.rightColor = rightColor; } public int getLineColor() { return lineColor; } public void setLineColor(int lineColor) { this.lineColor = lineColor; } public int getSelectLeftColor() { return selectLeftColor; } public void setSelectLeftColor(int selectLeftColor) { this.selectLeftColor = selectLeftColor; } public int getSelectRightColor() { return selectRightColor; } public void setSelectRightColor(int selectRightColor) { this.selectRightColor = selectRightColor; } public int getLefrColorBottom() { return lefrColorBottom; } public void setLefrColorBottom(int lefrColorBottom) { this.lefrColorBottom = lefrColorBottom; } public int getRightColorBottom() { return rightColorBottom; } public void setRightColorBottom(int rightColorBottom) { this.rightColorBottom = rightColorBottom; } }
  • 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
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 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
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333

3.具體使用:

private void initChatView() {

        myChartView.setLefrColorBottom(getResources().getColor(R.color.leftColorBottom)); myChartView.setLeftColor(getResources().getColor(R.color.leftColor)); myChartView.setRightColor(getResources().getColor(R.color.rightColor)); myChartView.setRightColorBottom(getResources().getColor(R.color.rightBottomColor)); myChartView.setSelectLeftColor(getResources().getColor(R.color.selectLeftColor)); myChartView.setSelectRightColor(getResources().getColor(R.color.selectRightColor)); myChartView.setLineColor(getResources().getColor(R.color.xyColor)); chartList = new ArrayList<>(); relativeLayout = (RelativeLayout) findViewById(R.id.linearLayout); relativeLayout.removeView(llChart); Random random = new Random(); while (chartList.size() < 24) { int randomInt = random.nextInt(100); chartList.add((float) randomInt); } myChartView.setList(chartList); myChartView.setListener(new MyChartView.getNumberListener() { @Override public void getNumber(int number, int x, int y) { relativeLayout.removeView(llChart); //反射加載點擊柱狀圖彈出布局 llChart = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.layout_shouru_zhichu, null); TextView tvZhichu = (TextView) llChart.findViewById(R.id.tv_zhichu); TextView tvShouru = (TextView) llChart.findViewById(R.id.tv_shouru); tvZhichu.setText((number + 1) + "月支出" + " " + chartList.get(number * 2)); tvShouru.setText ( "收入: " + chartList.get(number * 2 + 1)); llChart.measure(0, 0);//調用該方法后才能獲取到布局的寬度 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); params.leftMargin = x - 100; if (x - 100 < 0) { params.leftMargin = 0; } else if (x - 100 > relativeLayout.getWidth() - llChart.getMeasuredWidth()) { //設置布局距左側屏幕寬度減去布局寬度 params.leftMargin = relativeLayout.getWidth() - llChart.getMeasuredWidth(); } llChart.setLayoutParams(params); relativeLayout.addView(llChart); } }); }
  • 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
  • 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

經過以上步驟,我們的雙條豎向柱狀圖就繪制完成了,也顯示出來了。其實自己坐下來仔細拿筆算一下,畫一下,也沒有想象的那么難。至於單條和橫向的實現原理都一樣,比這個要簡單的多。哦對了,橫向的我只是自定義了一個橫向的柱狀圖View,然后用ListView顯示的各個部門的具體內容。好了最后感謝我的朋友幫了我很多忙Young_Kai,大家也可以看看他的博客,很不錯的。

代碼我已經上傳我的Github,歡迎大家star,fork: 
https://github.com/Hankkin/MyCartDemo

最后推薦一下老劉解析的MPChart

http://blog.csdn.net/qq_26787115


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM