android 实现淘宝收益图的折线
实现的效果我一会贴上,我先说下原理,我们知道要实现在canvas上画线,不就是要搞一个paint嘛,然后首先肯定要设置下paint的属性,那么画文字呢,不就是Textpaint吗,
对,就是这么简单,接下来怎么画,折线图主要分为X轴和y轴,x轴表示日期,y表示收益,好,说道这里,大家应该知道怎么去做了,下面直接贴代码,
这个方法是,画x,y坐标系的,以及上面的日期和收益了
private void drawCoordinate(Canvas canvas) { //坐标系画笔 Paint coordinatePaint = new Paint(); coordinatePaint.setAntiAlias(true); coordinatePaint.setStrokeWidth(1); coordinatePaint.setColor(getResources().getColor(R.color.c5)); //坐标系文字画笔 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); } }
但是产品有个需求啊,就是点击当前日期可以查看我的收益,并且在交汇点上展示出来
private void drawCurve(Canvas canvas) { Paint curvePaint = new Paint();//曲线画笔 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; } }
点击交汇点,有文字提示说明,
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); //描绘交汇圆点 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); }
好了核心的代码就这么多了,由于我们把它当做的是控件再用,那么我们在初始化的时候,肯定会引入一些自定义的样式表,
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); }
样式表文件我就不多说了,行如下面的格式,
<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>
最后贴上个效果图,有需要的联系我吧,欢迎留言
git下载地址:https://github.com/xiangzhihong/lineview
android 实现淘宝收益图的折线的更多相关文章
- Android仿淘宝购物车demo
夏的热情渐渐退去,秋如期而至,丰收的季节,小编继续着实习之路,走着走着,就走到了购物车,逛过淘宝或者是京东的小伙伴都知道购物车里面的宝贝可不止一件,对于爱购物的姑娘来说,购物车里面的商品恐怕是爆满,添 ...
- Android之淘宝商品列表长按遮罩效果
先来看看淘宝.唯品会长按商品的效果,以及简单Demo的效果: 首先分析一下场景: 长按条目时,弹出遮罩的效果遮挡在原来的条目布局上: 页面滑动或点击其他的条目,上一个正在遮罩的条目遮罩消 ...
- Android仿淘宝继续上拉进入商品详情页的效果,使用双Fragment动画切换;
仿淘宝继续上拉进入商品详情页的效果,双Fragment实现: 动画效果: slide_above_in.xml <?xml version="1.0" encoding=&q ...
- Android -- 仿淘宝广告条滚动
1,在赶项目的时候我们经常会实现下面这个功能,及添加滚动条广告广播,先看一下淘宝的效果 2,这次实现效果主要使用Android自带的ViewFlipper控件,先来看一下我们的它的基本属性和基本方法吧 ...
- Android仿淘宝头条滚动广告条
之前我使用TextView+Handler+动画,实现了一个简单的仿淘宝广告条的滚动,https://download.csdn.net/download/qq_35605213/9660825: 无 ...
- Android 仿淘宝头条竖直跑马灯式新闻标题及“分页思想
在淘宝App的首页中间位置,有一块小小的地方在不知疲倦地循坏滚动着头条标题(见下图的红框区域),这样的设计无疑能够在有限的手机屏幕上展示更丰富的内容.而实现这一功能需要用到的控件就是我在上一篇文章中提 ...
- Android 仿淘宝属性标签页
直接看效果图相信这样的效果很多,我之前在网上找了很久没找到自己想要的! <?xml version="1.0" encoding="utf-8"?> ...
- Android画柱状图,圆形图和折线图的demo
效果图如下: demo下载地址:http://files.cnblogs.com/hsx514/wireframe.zip
- jquery实现淘宝动态图展示商品
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
随机推荐
- Java基本语法-----java运算符
这块的东西比较多 我写了太慢了 于是在word里写好贴出来供大家一起学习 运算符 -赋值运算符 -比较运算符 -逻辑运算符 -位运算符 -移位操作符 -三元运算符 [正在看本人博客的这位童鞋,我看你气 ...
- java虚拟机 jvm 出入java栈 栈空间内存分配
java栈空间是一块线程私有的内存空间,java堆和程序数据密切相关,那么java栈就是和线程执行密切相关.线程最基本的执行行为就是函数的调用.每次函数调用其实是通过java栈传递数据的. 数据结构中 ...
- 安卓自定义View实现图片上传进度显示(仿QQ)
首先看下我们想要实现的效果如下图(qq聊天中发送图片时的效果): 再看下图我们实现的效果: 实现原理很简单,首先我们上传图片时需要一个进度值progress,这个不管是自己写的上传的方法还是使用第三方 ...
- Druid VS Antlr4
DRUID VS ANTLR4 测试方法 环境:x86_64,eclipse kepler,jdk 6 测试对象:antlr v4,druid手写sql parser模块 测试过程:分别采用单线程.多 ...
- dbcp连接池不合理的锁导致连接耗尽
应用报错,表象来看是连接池爆满了. org.springframework.transaction.CannotCreateTransactionException: Could not open J ...
- iOS中 按钮和标题完美各种排列/完美教程 韩俊强的博客
每日更新关注:http://weibo.com/hanjunqiang 新浪微博! 前言:最近常常用到按钮和相应标题的组合,当按钮设置图片加标题时,触发范围较小,不易触发,最重要的是还要调试偏移量, ...
- Objc将数据写入iOS真机的plist文件中
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 如何写入模拟器的博文在 这里 但是这对真机不管用,因为在真机环 ...
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(五):设置背景
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- 关于Java的移位运算符
/** * 测试移位运算符<br/> * "<<" 左移 : 右侧补0<br/> * ">>" 带符号右移 : ...
- Android5.1设备无法识别exFAT文件系统的64G TF卡问题
64G TF卡刚买回来的时候默认exFAT文件系统,在电脑端(XP和WIN7)可以识别,但在我们Android5.1S设备无法识别,采用guiformat工具格式化为FAT32文件系统后才可以正常识别 ...