Android自定义view之天气折线图
来源:互联网 发布:淘宝买东西有质量问题 编辑:程序博客网 时间:2024/05/22 06:04
Android自定义view之天气折线图
最近公司一个项目需求,需要添加一个折线图,能够显示七天的天气信息。当然这个需求并不是很难,网上也有很多相关的例子,但是为了巩固下自定义view的基础,所以我决定还是自己写一个玩玩。不啰嗦,先上效果图(demo没有美化,比较简陋)
看了效果图,是不是感觉比较简单,麻雀虽小,但是五脏俱全,这里面囊括自定义view的核心。
先介绍下自定义view里面的几个核心方法,后面我们都有用到的。
OnMeasure 这个负责测量的,一般我习惯在这里计算自定义view需要的一些值,比如说间距,大小等。
OnDraw 听这个名字就知道是绘制了,也是这个demo的最重要的地方了。
分析
两点确定一条线,这个概念大概我们在读小学的时候老师就应该教过我们吧,所以我们绘制折线的时候也是要依据这个概念了。点是通过XY来确定的,这里X是比较简单确定,因为都是相同的间隔,难点就是Y了。
想要知道Y坐标也是很简单的,在七天温度中,我们可以知道最高温与最低温相差多少,然后也可以知道我们的绘制区域的高度,最后就可以得知一个温度所占的高度。然后用每一个温度去减去最低温,就可以得与最低温相差多少,然后就很轻松的知道这个温度的高度了。
声明需要的值
将一些常用的值写在上面是为了便于以后修改,万一哪天产品经理要你改下颜色什么的,一下就可以搞定了,不用到处去找。
/** * view的总高度 */ private int mViewHeight; /** * view的总宽度 */ private int mViewWidth; /** * 温度字体大小 */ private int mTempTextSize=22; /** * 温度字体颜色 */ private int mTempTextColor=Color.GREEN; /** * 线的宽度 */ private int mWeaLineWidth = 3; /** * 圆点的半径 */ private int mWeaDotRadius = 5; /** * 画圆圈的画笔与画线的笔 */ private Paint mDotPaint; private Paint mLinePaint; /** * 画灰色线的笔与画温度的笔 */ private Paint mGrayLinePaint; private TextPaint mTempPaint; /** * 文字和点的间距 */ private int mTextDotDistance = 20; /** * 坐标点文字偏移量 */ private static final int POINT_TEXT_OFFSET = 10; /** * 最高温集合中温度差 */ private float mHighsTempest; /** * 最低温集合中温度差 */ private int mLowsTempest; /** * 最高温数组 */ private List<Integer> mHighs; /** * 最低温数组 */ private List<Integer> mLows; /** * 与顶部和底部的间距 */ private final int mMarginTopAndrBottom=15; /** *每个点的间隔X轴 */ private int mInterval; /** * 第一个点的X坐标 */ private float mFristX; /** * 折线图高度(单个) */ private float mLineHeight; /** * 灰色线的间隔 */ private int mSpace=200; //高温线的颜色 private final static int LINE_COLOR_HIGH=Color.RED; //低温线的颜色 private final static int LINE_COLOR_LOW=Color.BLUE;
绘制线
因为七个点,所以只要画6条线就OK了.
private void drawLine(Canvas canvas) { float highsBaseY=mLineHeight/mHighsTempest;//最高温中每隔一度对应相隔多少y坐标 float lowsBaseY=mLineHeight/mLowsTempest;//最低温中每隔一度对应相隔多少y坐标 float y1,y2=0f;//y1起点y坐标,y2 终点y坐标 float x1,x2=0f; //绘制高温 for (int i=0;i<mHighs.size()-1;i++){ x1=mFristX+mInterval*i; x2=mFristX+mInterval*(i+1); y1=mHighs.get(i)-mHighsLowest; y1=highsBaseY*y1-(mMarginTopAndrBottom*3); y1=mLineHeight-y1; y2=mHighs.get(i+1)-mHighsLowest; y2=highsBaseY*y2-(mMarginTopAndrBottom*3); y2=mLineHeight-y2; canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); canvas.drawLine(x1,y1,x2,y2,mLinePaint); } //绘制低温 mLinePaint.setColor(Color.BLUE); for (int i=0;i<mLows.size()-1;i++){ x1=mFristX+mInterval*i; x2=mFristX+mInterval*(i+1); y1=mLows.get(i)-mLowsLowsest; y1=lowsBaseY*y1-(mMarginTopAndrBottom*3); y1=mLineHeight-y1+mSpace; y2=mLows.get(i+1)-mLowsLowsest; y2=lowsBaseY*y2-(mMarginTopAndrBottom*3); y2=mLineHeight-y2+mSpace; canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); canvas.drawLine(x1,y1,x2,y2,mLinePaint); } }
绘制圆圈
private void drawDot(Canvas canvas) { float highsBaseY=mLineHeight/mHighsTempest;//最高温中每隔一度对应相隔多少y坐标 float lowsBaseY=mLineHeight/mLowsTempest;//最低温中每隔一度对应相隔多少y坐标 // Log.e("smile","highsBaseY "+highsBaseY+" lowsBaseY"+lowsBaseY); float y=0f; float x=0f; for (int i = 0; i < mHighs.size(); i++) { y=mHighs.get(i)-mHighsLowest; x=mFristX+mInterval*i; y=highsBaseY*y-(mMarginTopAndrBottom*3); y=mLineHeight-y; canvas.drawCircle(x,y,mWeaDotRadius,mDotPaint); } for (int i = 0; i < mLows.size(); i++) { // Log.e("smile","lowset "+mLowsLowsest+" "+mLows.get(i)+" mlineHeight "+mLineHeight); y=mLows.get(i)-mLowsLowsest; y=lowsBaseY*y-(mMarginTopAndrBottom*3); y=mLineHeight-y+mSpace; canvas.drawCircle(mFristX+mInterval*i,y,mWeaDotRadius,mDotPaint); } }
绘制温度
记住一个是在上面,一个是在下面,
private void drawTemp(Canvas canvas){ float baseY=mLineHeight/mHighsTempest;//每隔一度对应相隔多少y坐标 float lowsBaseY=mLineHeight/mLowsTempest;//最低温中每隔一度对应相隔多少y坐标 float y=0f; float x=0f; for (int i = 0; i < mHighs.size(); i++) { y=mHighs.get(i)-mHighsLowest; y=baseY*y-(mMarginTopAndrBottom*3); y=mLineHeight-y-mTextDotDistance; x=mFristX+mInterval*i-POINT_TEXT_OFFSET; canvas.drawText(String.valueOf(mHighs.get(i)),x,y,mTempPaint); } for (int i = 0; i < mHighs.size(); i++) { y=mLows.get(i)-mLowsLowsest; y=lowsBaseY*y-(mMarginTopAndrBottom*3); y=mLineHeight-y+mSpace+mTextDotDistance+10; x=mFristX+mInterval*i-POINT_TEXT_OFFSET; canvas.drawText(String.valueOf(mLows.get(i)),x,y,mTempPaint); } }
最后贴上这个类的源码:传送门
代码都有详细的注释。周五万岁,,,
0 0
- Android自定义view之天气折线图
- 自定义View实现天气折线图效果
- WeatherView -- 自定义View实现天气折线图
- 自定义View之仿小米MIUI天气24小时预报折线图
- 自定义View之折线图
- Android 自定义View 折线图
- Android 自定义View之绘制折线图、曲线图
- Android之自定义控件实现天气温度折线图和饼状图
- 自定义View之颜色渐变折线图
- 自定义View(二)之折线图
- 自定义View之颜色渐变折线图
- Android 自定义View,实现折线图
- Android 自定义View,实现折线图
- Android 自定义View -- 简约的折线图
- Android 自定义View画天气预报折线图
- Android自定义View-折线趋势图
- Android 自定义view绘制折线图
- 自定义View--折线图
- jdk1.8.0_45的安装和环境配置
- usb设备probe过程
- 求两点之间的距离,类中有静变量和静态方法
- 内容相近博客
- The Art of Public Speaking——读后感
- Android自定义view之天气折线图
- iPhone 6P下试用zabbix控制端
- git remote管理远程仓库
- javascript 入门
- ubuntu 下安装 texlive&…
- 使用gdb调试段错误
- Maven使用
- mtk驱动
- 简单面试题--值传递还是引用传递