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 ...
随机推荐
- Android 高级控件(七)——RecyclerView的方方面面
Android 高级控件(七)--RecyclerView的方方面面 RecyclerView出来很长时间了,相信大家都已经比较了解了,这里我把知识梳理一下,其实你把他看成一个升级版的ListView ...
- React Native组件只Image
不管在Android还是在ios原生的开发中,图片都是作为控件给出来的,在RN中也有这么一个控件(Image).根据官网的资料,图片分为本地静态图片,网络图片和混合app资源.一下分类介绍来源官网. ...
- Java基本语法-----java数据类型的转换
前言 Java中可以进行不同数据类型的加减乘除运算吗?是可以的.在算术运算符中已经体验过如果两个整数(int)相除会去掉小数部分.如果需要保留小数部分,可以让除数或者被除数变为double类型的(5变 ...
- Struts 2 之拦截器
拦截器概述 Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP(Aspect Oriented Progr ...
- JDK的安装以及配置
JDK的安装以及配置 JDK(Java Development Kit),顾名思义,是 Java 语言的软件开发工具包(SDK). Android发开使用Java语言,所以装JDK是Android开发 ...
- Swift的print不换行打印的方法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) swift大多数情况下我们直接用默认的print函数打印就可以 ...
- 混合开发(一)——WebView开发高级技巧之加载网页以及JavaScript,加载进度条
混合开发(一)--WebView开发高级技巧之加载网页以及JavaScript,加载进度条 现在关于混合开发也越来越多了,很多人喜欢跟随,比如HB,比如RN,其实这东西很早就有这么一个概念了,而且说实 ...
- 【Android应用开发】Android Studio - MAC 版 - 快捷键详解
博客地址 : http://blog.csdn.net/shulianghan/article/details/47321177 作者 : 韩曙亮 要点总结 : -- 熟练使用快捷键 : 在任何编程环 ...
- Qt应用程序中设置字体
Qt应用程序中设置字体 应用程序中经常需要设置字体,例如office软件或者是其他的编辑器软件等等.这里主要涉及到如下几个概念:字体,字号以及风格(例如:粗体,斜体,下划线等等).Qt里面也有对应的类 ...
- android api 镜像站
项目地址:https://github.com/msdx/androiddoc 访问短址: http://androiddoc.qiniudn.com/