Android開(kāi)發(fā)實(shí)現(xiàn)繪制淘寶收益圖折線效果示例
本文實(shí)例講述了Android開(kāi)發(fā)實(shí)現(xiàn)繪制淘寶收益圖折線效果。分享給大家供大家參考,具體如下:
實(shí)現(xiàn)的效果我一會(huì)貼上,我先說(shuō)下原理,我們知道要實(shí)現(xiàn)在canvas上畫(huà)線,不就是要搞一個(gè)paint嘛,然后首先肯定要設(shè)置下paint的屬性,那么畫(huà)文字呢,不就是Textpaint嗎,對(duì),就是這么簡(jiǎn)單,接下來(lái)怎么畫(huà),折線圖主要分為X軸和y軸,x軸表示日期,y表示收益,好,說(shuō)道這里,大家應(yīng)該知道怎么去做了,下面直接貼代碼
這個(gè)方法是,畫(huà)x,y坐標(biāo)系的,以及上面的日期和收益了
private void drawCoordinate(Canvas canvas) { //坐標(biāo)系畫(huà)筆 Paint coordinatePaint = new Paint(); coordinatePaint.setAntiAlias(true); coordinatePaint.setStrokeWidth(1); coordinatePaint.setColor(getResources().getColor(R.color.c5)); //坐標(biāo)系文字畫(huà)筆 TextPaint coordinateTextPaint = new TextPaint(); coordinateTextPaint.setAntiAlias(true); coordinateTextPaint.setTextSize(scaleTextSize); coordinateTextPaint.setAntiAlias(true); coordinateTextPaint.setColor(scaleTextColor); coordinateTextPaint.setTextAlign(Align.CENTER); //水平的刻度線 float verticalScaleStep = getVerticalScaleStep(); coordinateTextPaint.setTextAlign(Align.RIGHT); float textHeight = getTextHeight(coordinateTextPaint, "8"); for (int i = 0; i < maxVerticalScaleValue; i++) { float y = getHeight() - bottomPadding - (verticalScaleStep * i); canvas.drawLine(leftPadding, y, getWidth() - rightPadding, y, coordinatePaint); canvas.drawText(i + "", leftPadding - 13, y + textHeight / 2, coordinateTextPaint); } //垂直的刻度線 float horizontalScaleStep = getHorizontalScaleStep(); for (int i = 0; i < line.getSize(); i++) { float x = leftPadding + (horizontalScaleStep * i); if (i == 0) { canvas.drawLine(x, topPadding, x, getHeight() - bottomPadding, coordinatePaint); } coordinateTextPaint.setColor(mTouchIndex == i ? verticalLineColor : scaleTextColor); coordinateTextPaint.setTextAlign(i == 0 ? Align.LEFT : Align.CENTER); canvas.drawText(line.getPoint(i).getX(), x, getHeight() - bottomPadding + textHeight + 10, coordinateTextPaint); } }
但是產(chǎn)品有個(gè)需求啊,就是點(diǎn)擊當(dāng)前日期可以查看我的收益,并且在交匯點(diǎn)上展示出來(lái)
private void drawCurve(Canvas canvas) { Paint curvePaint = new Paint();//曲線畫(huà)筆 curvePaint.setColor(curveColor); curvePaint.setAntiAlias(true); curvePaint.setStrokeWidth(curveStrokeWidth); float horizontalScaleStep = getHorizontalScaleStep(); float lastXPixels = 0, newYPixels = 0; float lastYPixels = 0, newXPixels = 0; float useHeight = getHeight() - bottomPadding - topPadding; for (int i = 0; i < line.getSize(); i++) { float yPercent = line.getPoint(i).getY() / maxVerticalScaleValue; if (i == 0) { lastXPixels = leftPadding + i * horizontalScaleStep; lastYPixels = getHeight() - bottomPadding - useHeight * yPercent; } else { newXPixels = leftPadding + i * horizontalScaleStep; newYPixels = getHeight() - bottomPadding - useHeight * yPercent; canvas.drawLine(lastXPixels, lastYPixels, newXPixels, newYPixels, curvePaint); lastXPixels = newXPixels; lastYPixels = newYPixels; } line.getPoint(i).fLineX = lastXPixels; line.getPoint(i).fLineY = lastYPixels; } }
點(diǎn)擊交匯點(diǎn),有文字提示說(shuō)明,
private void drawTipRect(Canvas canvas) { if (mTouchIndex == -1) return; LinePoint point = line.getPoint(mTouchIndex); float x = point.fLineX; float y = point.fLineY; // 描繪豎線 Paint paint = new TextPaint(); PathEffect effects = new DashPathEffect(new float[]{5, 5, 5, 5}, 1); paint.setPathEffect(effects); paint.setAntiAlias(true); paint.setStrokeWidth(verticalLineStrokeWidth); paint.setColor(verticalLineColor); canvas.drawLine(x, topPadding, x, getHeight() - bottomPadding, paint); //描繪交匯圓點(diǎn) paint.setPathEffect(null); paint.setStyle(Paint.Style.FILL_AND_STROKE); paint.setColor(Color.WHITE); canvas.drawCircle(x, y, circleRadius, paint); paint.setStyle(Paint.Style.STROKE); paint.setColor(circleColor); paint.setStrokeWidth(circleStrokeWidth); canvas.drawCircle(x, y, circleRadius, paint); float midY = (topPadding + getHeight() - bottomPadding) / 2; float midX = (leftPadding + getWidth() - rightPadding) / 2; //描繪圓角矩形 TextPaint textPaint = new TextPaint(); textPaint.setTextSize(tipTextSize); textPaint.setTextAlign(Align.CENTER); textPaint.setColor(tipTextColor); textPaint.setAntiAlias(true); String label = tipPrefix + point.getY(); float textWidth = textPaint.measureText(label) + 15; float textHeight = getTextHeight(textPaint, label) + 8; float hMargin = 10;//水平間距 float vMargin = 8;//垂直間距 float w = textWidth + hMargin * 2;//寬 float h = textHeight + vMargin * 2;//高 RectF rect = new RectF(); if (x > midX) { rect.right = x - hMargin; rect.left = x - w; } else { rect.left = x + hMargin; rect.right = x + w; } if (y > midY) { rect.top = y - h; rect.bottom = y - vMargin; } else { rect.bottom = y + h; rect.top = y + vMargin; } Paint roundRectPaint = new Paint(); roundRectPaint.setColor(tipRectColor); roundRectPaint.setStyle(Paint.Style.FILL); roundRectPaint.setAntiAlias(true); canvas.drawRoundRect(rect, 3, 3, roundRectPaint); // 描繪圓角矩形中間的文字 float roundTextX = (rect.left + rect.right) / 2; float roundTextY = (rect.top + rect.bottom + getTextHeight(textPaint, label)) / 2; canvas.drawText(label, roundTextX, roundTextY, textPaint); }
好了核心的代碼就這么多了,由于我們把它當(dāng)做的是控件再用,那么我們?cè)诔跏蓟臅r(shí)候,肯定會(huì)引入一些自定義的樣式表,
private void initViews(AttributeSet attrs, int defStyle) { TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.LineGraph, defStyle, 0); scaleTextSize = typedArray.getDimension(R.styleable.LineGraph_scale_text_size, 20); scaleTextColor = typedArray.getColor(R.styleable.LineGraph_scale_text_color, getResources().getColor(R.color.c5)); tipRectColor = typedArray.getColor(R.styleable.LineGraph_tip_rect_color, getResources().getColor(R.color.c8)); tipTextSize = typedArray.getDimension(R.styleable.LineGraph_tip_text_size, 22); tipTextColor = typedArray.getColor(R.styleable.LineGraph_tip_text_color, getResources().getColor(R.color.c12)); curveStrokeWidth = typedArray.getDimension(R.styleable.LineGraph_curve_stroke_width, 4); curveColor = typedArray.getColor(R.styleable.LineGraph_curve_color, getResources().getColor(R.color.c8)); verticalLineStrokeWidth = typedArray.getDimension(R.styleable.LineGraph_vertical_line_stroke_width, 2); verticalLineColor = typedArray.getColor(R.styleable.LineGraph_vertical_line_color, getResources().getColor(R.color.c8)); circleStrokeWidth = typedArray.getDimensionPixelSize(R.styleable.LineGraph_circle_stroke_width, 3); circleColor = typedArray.getColor(R.styleable.LineGraph_circle_color, getResources().getColor(R.color.c8)); circleRadius = typedArray.getDimensionPixelSize(R.styleable.LineGraph_circle_radius, 7); typedArray.recycle(); bottomPadding = dip2px(getContext(), 20); topPadding = dip2px(getContext(), 10); leftPadding = dip2px(getContext(), 20); rightPadding = dip2px(getContext(), 10); }
樣式表文件我就不多說(shuō)了,行如下面的格式,
<declare-styleable name="LineGraph"> <attr name="scale_text_size" format="dimension" /> <attr name="scale_text_color" format="color" /> <attr name="tip_text_size" format="dimension" /> <attr name="tip_text_color" format="color" /> <attr name="tip_rect_color" format="color" /> <attr name="curve_stroke_width" format="dimension" /> <attr name="curve_color" format="color" /> <attr name="vertical_line_stroke_width" format="dimension" /> <attr name="vertical_line_color" format="color" /> <attr name="circle_stroke_width" format="dimension" /> <attr name="circle_color" format="color" /> <attr name="circle_radius" format="dimension" /> </declare-styleable>
最后貼上個(gè)效果圖:
git下載地址:https://github.com/xiangzhihong/lineview
或者點(diǎn)擊此處本站下載。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Android圖形與圖像處理技巧總結(jié)》、《Android開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android調(diào)試技巧與常見(jiàn)問(wèn)題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android自定義可左右滑動(dòng)和點(diǎn)擊的折線圖
- Android繪制動(dòng)態(tài)折線圖
- Android自定義控件實(shí)現(xiàn)折線圖
- Android HelloChart開(kāi)源庫(kù)圖表之折線圖的實(shí)例代碼
- Android MPAndroidChart開(kāi)源庫(kù)圖表之折線圖的實(shí)例代碼
- Android自定義View簡(jiǎn)易折線圖控件(二)
- 詳解Android圖表 MPAndroidChart折線圖
- Android自定義View實(shí)現(xiàn)折線圖效果
- Android開(kāi)發(fā)之天氣趨勢(shì)折線圖
- MPAndroidChart開(kāi)源圖表庫(kù)的使用介紹之餅狀圖、折線圖和柱狀圖
- Android實(shí)現(xiàn)折線走勢(shì)圖
相關(guān)文章
Android應(yīng)用開(kāi)發(fā)中使用GridView網(wǎng)格布局的代碼示例
GridView布局比較基礎(chǔ),可以取代已經(jīng)逐漸淡出人們視線的TableLayout,這里我們就來(lái)看一下Android應(yīng)用開(kāi)發(fā)中使用GridView網(wǎng)格布局的代碼示例:2016-06-06Android Studio打包H5網(wǎng)址頁(yè)面,封裝成APK
大家好,本篇文章主要講的是Android Studio打包H5網(wǎng)址頁(yè)面,封裝成APK,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12Android提高之多級(jí)樹(shù)形菜單的實(shí)現(xiàn)方法
這篇文章主要介紹了Android多級(jí)樹(shù)形菜單的實(shí)現(xiàn)方法,很實(shí)用的功能,需要的朋友可以參考下2014-08-08flutter日期選擇器 flutter時(shí)間選擇器
這篇文章主要為大家詳細(xì)介紹了flutter日期選擇器,flutter時(shí)間選擇器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Android自定義Notification添加點(diǎn)擊事件
這篇文章主要為大家詳細(xì)介紹了Android自定義Notification添加點(diǎn)擊事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11解析Android中實(shí)現(xiàn)滑動(dòng)翻頁(yè)之ViewFlipper的使用詳解
有一些場(chǎng)景,我們需要向用戶(hù)展示一系列的頁(yè)面。比如我們正在開(kāi)發(fā)一個(gè)看漫畫(huà)的應(yīng)用,可能就需要向用戶(hù)展示一張一張的漫畫(huà)圖片,用戶(hù)使用手指滑動(dòng)屏幕,可以在前一幅漫畫(huà)和后一幅漫畫(huà)之間切換。這個(gè)時(shí)候ViewFlipper就是一個(gè)很好的選擇2013-05-05