这段时间的自定义View学习,学会了绘制柱状图、绘制折线图、绘制进度控件,那我们今天就来聊聊另外一种自定义的View,这就是我们常见的七日年化收益折线图效果。先看看长什么样。

这就是效果图了,元素相对而言还是比较多的,这里有线、柱状图、文字、折线、点等等。看起来好像很复杂,但是呢,只要一步一步的实现,那还是可以达到这种效果的,之前我们说过的, 自定义View,就像是在photo shop里面画图,想要什么就画什么,我们可以有很多的画笔工具,也可以有很多的图层。

先看看我们这一次用到哪些变量。

    private Paint mTextPaint, mLinePaint,mPathPaint,mPointPaint;//柱状图的宽度private float mPaintRectWidth;//路径private Path mPath;//高跟宽private float mWidth, mHeight;//柱状图的数量private final float mCount = 6;//偏移量private final float offsets=1;private float mRectHeight;//x轴的坐标private List<Float> xline=new ArrayList<Float>();//Y轴的坐标private List<Float> yline=new ArrayList<Float>();//左边文字private float []x={2.46f,2.45f,2.44f,2.43f,2.42f,2.41f,2.40f};//底部文字private String [] day={"07-01","07-02","07-03","07-04","07-05","07-06","07-07"};

注释标记的也是够详细了,为了大家能够看得懂,也为了提高的博客质量,我们注意到,这里有文字,有数量,基本涵盖了我们这里索要用到的所有的变量。

下面开始初始化操作。

private void initView() {//绘制线和文字的颜色mTextPaint = new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setColor(Color.parseColor("#cccccc"));mTextPaint.setTextSize(25);mTextPaint.setStrokeWidth(1);//绘制折线图的点mPointPaint= new Paint();mPointPaint.setAntiAlias(true);mPointPaint.setColor(Color.parseColor("#000000"));mPointPaint.setTextSize(25);mPointPaint.setStrokeWidth(5);//绘制柱状图的画笔mLinePaint = new Paint();mLinePaint.setAntiAlias(true);//绘制折线图的画笔mPathPaint= new Paint();mPathPaint.setAntiAlias(true);mPathPaint.setColor(Color.parseColor("#ff0000"));mPathPaint.setStyle(Style.STROKE);//折线图的路径mPath=new Path();}

这里主要就是给画笔初始化,可以看到每一个画笔的颜色、宽度都是不一样的,值的注意的是,这里面的画笔并没有设置镂空样式。

接下来我们看看怎么去赋值,老规矩,我们还是选择在onSizeChange()里面进行赋值,代码如下:

    @Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mWidth=(float)(getWidth()-getWidth()*0.1);mHeight=(float)(getHeight()-getHeight()*0.1);mRectHeight=(float)(getHeight()-getHeight()*0.1);mPaintRectWidth=(float) (mWidth*0.8/mCount);mLinePaint.setStrokeWidth(mPaintRectWidth);}

跟之前的不一样,我们以前所要用的宽度跟高度,直接就是使用方法里的,但是现在我们没有这么做,例如:(float)(getWidth()-getWidth()*0.1);我们进行了一定的处理,这样可以提高页面的舒适性,提高用户体验。

好了,准备工作做好了,接下来看看onDraw方法里面的操作,代码如下:

    @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);onDrawRect(canvas);     onDrawLine(canvas);canvasPath(canvas);}

哟呵,怎么这么简单,就三个东西?对的,就是这么简单粗暴,从名字中也可以看出,第一个是绘制矩形,第二个绘制线,第三个就是绘制折线。是不是很快呢,下面看看具体的实现方式。

第一个方法:

    //绘制6个矩形private void onDrawRect(Canvas canvas) {for (int i = 0; i < 7; i++) {if (i%2==0) {mLinePaint.setColor(Color.parseColor("#eeeeee"));}else {mLinePaint.setColor(Color.parseColor("#ece1f3"));}   float left  =(float) (mWidth * 0.4 / 2 + mPaintRectWidth * i + offsets);float right=(float) (mWidth * 0.4 / 2 + mPaintRectWidth* (i + 1));canvas.drawRect(left,(float)(mRectHeight*0.01),right, mHeight, mLinePaint);}}

第二个:

    //绘制网格线private void onDrawLine(Canvas canvas){//第一条线canvas.drawLine(mPaintRectWidth-mPaintRectWidth/2, (float)(mRectHeight*0.01), getWidth(),  (float)(mRectHeight*0.01), mTextPaint);//定义这里高度float height;//横七条for (float i = 0; i < 7; i++) {//从上到下if (i==0) {height=i;}else {height=mRectHeight*(i/6);float size=mTextPaint.measureText(x[(int)i]+"");//绘制线canvas.drawLine(mPaintRectWidth+mPaintRectWidth/2, height, getWidth(),  height, mTextPaint);//绘制左边Y轴的文字canvas.drawText(x[(int)i]+"", (float)(mPaintRectWidth-mPaintRectWidth*0.35), height+size/5, mTextPaint);}}//竖七条canvas.drawLine((float) (mPaintRectWidth-mPaintRectWidth/2),0, (float) (mPaintRectWidth-mPaintRectWidth/2),  mHeight, mTextPaint);for (float i = 0; i < 7; i++) {//从左到右canvas.drawLine((float) (mWidth * 0.4 / 2 + mPaintRectWidth * i),0, (float) (mWidth * 0.4 / 2 + mPaintRectWidth * i),  mHeight, mTextPaint);//绘制底边的日期文字canvas.drawText(day[(int) i], (float) (mWidth * 0.34 / 2 + mPaintRectWidth * i), (float)(mHeight+mHeight*0.1), mTextPaint);//准备好下面折线图的X轴坐标xline.add((float) (mWidth * 0.4 / 2 + mPaintRectWidth * i));}//折线图的第一个点xline.add((float) (mPaintRectWidth-mPaintRectWidth/2));}

这里的代码相对较多,我专门加了许多的注释,可以用心的看看。

第三个绘制折线:

    //绘制折线路径public void canvasPath(Canvas canvas){for (int j = 0; j < yline.size(); j++) {float x=xline.get(j);float y =yline.get(j);float aftery=Math.initData(y);if (j==0) {mPath.moveTo(x,aftery );}else{mPath.lineTo(x,aftery );}canvas.drawPoint(x, aftery, mPointPaint);float size=mPointPaint.measureText(y+"");canvas.drawText(y+"", (float)(x-size/2), (float)(aftery+size*0.25), mPointPaint);}canvas.drawPath(mPath, mPathPaint);}

这里的绘制折线包括绘制线、点、文字、还有文字的转换、但是这个转换可以根据自己的需求来进行定制。

最后向外面暴露一个方法,用于更新坐标。

    //用于设置Y轴的坐标值public void setDataY( List<Float> yline) {this.yline.clear();this.yline=yline;}//一个更新UI的方法public void invalidata(){invalidate();}

文字的转换我这里用一个自己的类去处理了,代码如下:

    public static float initData(float a){if (2.40f<=a&&a<2.41f) {a=540f-540f/(a/0.01f);}else if(2.41f<=a&&a<2.42f){a=480f-480f/(a/0.01f);}else if (2.42f<=a&&a<2.43f) {a=360f-360f/(a/0.01f);}else if (2.43f<=a&&a<2.44f) {a=270f-270f/(a/0.01f);}else if (2.44f<=a&&a<2.45f) {a=180f-180f/(a/0.01f);}else if (2.45f<=a&&a<2.46f) {a=90f-90f/(a/0.01f);}return a;}

以上就是逻辑的实现过程了。最后,我把所有代码贴上来:

AnnualyieldView.java

/*** 小瓶盖 2016年7月13日18:08:28* * @author Android自定义View——实现理财类APP七日年化收益折线图效果**相关博客地址 http://blog.csdn.net/qq_25193681*/
public class AnnualyieldView extends View {private Paint mTextPaint, mLinePaint,mPathPaint,mPointPaint;//柱状图的宽度private float mPaintRectWidth;//路径private Path mPath;//高跟宽private float mWidth, mHeight;//柱状图的数量private final float mCount = 6;//偏移量private final float offsets=1;private float mRectHeight;//x轴的坐标private List<Float> xline=new ArrayList<Float>();//Y轴的坐标private List<Float> yline=new ArrayList<Float>();//左边文字private float []x={2.46f,2.45f,2.44f,2.43f,2.42f,2.41f,2.40f};//底部文字private String [] day={"07-01","07-02","07-03","07-04","07-05","07-06","07-07"};public AnnualyieldView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView();}public AnnualyieldView(Context context, AttributeSet attrs) {super(context, attrs);initView();}public AnnualyieldView(Context context) {super(context);initView();}private void initView() {//绘制线和文字的颜色mTextPaint = new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setColor(Color.parseColor("#cccccc"));mTextPaint.setTextSize(25);mTextPaint.setStrokeWidth(1);//绘制折线图的点mPointPaint= new Paint();mPointPaint.setAntiAlias(true);mPointPaint.setColor(Color.parseColor("#000000"));mPointPaint.setTextSize(25);mPointPaint.setStrokeWidth(5);//绘制柱状图的画笔mLinePaint = new Paint();mLinePaint.setAntiAlias(true);//绘制折线图的画笔mPathPaint= new Paint();mPathPaint.setAntiAlias(true);mPathPaint.setColor(Color.parseColor("#ff0000"));mPathPaint.setStyle(Style.STROKE);//折线图的路径mPath=new Path();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mWidth=(float)(getWidth()-getWidth()*0.1);mHeight=(float)(getHeight()-getHeight()*0.1);mRectHeight=(float)(getHeight()-getHeight()*0.1);mPaintRectWidth=(float) (mWidth*0.8/mCount);mLinePaint.setStrokeWidth(mPaintRectWidth);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);onDrawRect(canvas);     onDrawLine(canvas);canvasPath(canvas);}//绘制6个矩形private void onDrawRect(Canvas canvas) {for (int i = 0; i < 7; i++) {if (i%2==0) {mLinePaint.setColor(Color.parseColor("#eeeeee"));}else {mLinePaint.setColor(Color.parseColor("#ece1f3"));}   float left  =(float) (mWidth * 0.4 / 2 + mPaintRectWidth * i + offsets);float right=(float) (mWidth * 0.4 / 2 + mPaintRectWidth* (i + 1));canvas.drawRect(left,(float)(mRectHeight*0.01),right, mHeight, mLinePaint);}}//绘制网格线private void onDrawLine(Canvas canvas){//第一条线canvas.drawLine(mPaintRectWidth-mPaintRectWidth/2, (float)(mRectHeight*0.01), getWidth(),  (float)(mRectHeight*0.01), mTextPaint);//定义这里高度float height;//横七条for (float i = 0; i < 7; i++) {//从上到下if (i==0) {height=i;}else {height=mRectHeight*(i/6);float size=mTextPaint.measureText(x[(int)i]+"");//绘制线canvas.drawLine(mPaintRectWidth+mPaintRectWidth/2, height, getWidth(),  height, mTextPaint);//绘制左边Y轴的文字canvas.drawText(x[(int)i]+"", (float)(mPaintRectWidth-mPaintRectWidth*0.35), height+size/5, mTextPaint);}}//竖七条canvas.drawLine((float) (mPaintRectWidth-mPaintRectWidth/2),0, (float) (mPaintRectWidth-mPaintRectWidth/2),  mHeight, mTextPaint);for (float i = 0; i < 7; i++) {//从左到右canvas.drawLine((float) (mWidth * 0.4 / 2 + mPaintRectWidth * i),0, (float) (mWidth * 0.4 / 2 + mPaintRectWidth * i),  mHeight, mTextPaint);//绘制底边的日期文字canvas.drawText(day[(int) i], (float) (mWidth * 0.34 / 2 + mPaintRectWidth * i), (float)(mHeight+mHeight*0.1), mTextPaint);//准备好下面折线图的X轴坐标xline.add((float) (mWidth * 0.4 / 2 + mPaintRectWidth * i));}//折线图的第一个点xline.add((float) (mPaintRectWidth-mPaintRectWidth/2));}//绘制折线路径public void canvasPath(Canvas canvas){for (int j = 0; j < yline.size(); j++) {float x=xline.get(j);float y =yline.get(j);float aftery=Math.initData(y);if (j==0) {mPath.moveTo(x,aftery );}else{mPath.lineTo(x,aftery );}canvas.drawPoint(x, aftery, mPointPaint);float size=mPointPaint.measureText(y+"");canvas.drawText(y+"", (float)(x-size/2), (float)(aftery+size*0.25), mPointPaint);}canvas.drawPath(mPath, mPathPaint);}//用于设置Y轴的坐标值public void setDataY( List<Float> yline) {this.yline.clear();this.yline=yline;}//一个更新UI的方法public void invalidata(){invalidate();}
}

MainActivity.java

/*** 小瓶盖 2016年7月13日18:08:28* * @author Android自定义View——实现理财类APP七日年化收益折线图效果**相关博客地址 http://blog.csdn.net/qq_25193681*/
public class MainActivity extends Activity {private AnnualyieldView annualyieldView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);annualyieldView=(AnnualyieldView) findViewById(R.id.line);initdata();}private void initdata() {List<Float> yline=new ArrayList<Float>();yline.add(2.420123f);yline.add(2.444122f);yline.add(2.45359f);yline.add(2.4206f);yline.add(2.4357f);yline.add(2.4228f);yline.add(2.4350f);annualyieldView.setDataY(yline);}}

布局文件activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.annualyield.MainActivity" ><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_margin="10dip"android:orientation="vertical" ><TextView android:layout_width="match_parent"android:layout_height="wrap_content"android:textColor="#888888"android:textSize="18sp"android:text="七日年化收益率(%)"/><com.example.annualyield.AnnualyieldView
            android:id="@+id/line"android:layout_width="match_parent"android:layout_height="200dip"android:layout_marginTop="10dip"android:layout_marginBottom="10dip" /></LinearLayout></RelativeLayout>

还有一个用于转换的类,Math.java

/*** 小瓶盖 2016年7月13日18:08:28* * @author Android自定义View——实现理财类APP七日年化收益折线图效果**相关博客地址 http://blog.csdn.net/qq_25193681*/
public class Math {public static float initData(float a){if (2.40f<=a&&a<2.41f) {a=540f-540f/(a/0.01f);}else if(2.41f<=a&&a<2.42f){a=480f-480f/(a/0.01f);}else if (2.42f<=a&&a<2.43f) {a=360f-360f/(a/0.01f);}else if (2.43f<=a&&a<2.44f) {a=270f-270f/(a/0.01f);}else if (2.44f<=a&&a<2.45f) {a=180f-180f/(a/0.01f);}else if (2.45f<=a&&a<2.46f) {a=90f-90f/(a/0.01f);}return a;}
}

以上就是代码的全部内容,我记得我大学的老实说,不懂的地方就自己多敲代码,多了就懂了,虽然那时候我不认同,但是现在觉得还是有一定道理,都是一样过来的,现在希望能够跟大家一起进步。

最后我附上源码:

Android自定义View——实现理财类APP七日年化收益折线图效果相关推荐

  1. 自定义View之仿小米MIUI天气24小时预报折线图

    本篇文章已授权微信公众号 hongyangAndroid(鸿洋)独家发布. 效果图 本控件是仿MIUI8天气24小时预报折线图,用小米手机的可以打开天气软件看一下.本文是对自定义View的练手作品,要 ...

  2. android自定义控件几种,Android 自定义View一个控件搞定多种水波纹涟漪扩散效果 - CSDN博客...

    效果图 实现思路 这个效果实现起来并不难,重要的是思路 此View满足了多种水波纹涟漪扩散效果,这要求它能满足很多的变化 根据上面的样式,可以看出此View需要满足以下变化 圆圈从中心可循环向外扩散 ...

  3. Android自定义View之上拉、下拉列表 头部元素跟随 缩放、平移效果的实现

    滑动ListView列表然后 listView上边的视图 跟随着上拉或者下拉的距离 自动放大或者缩小  视图里边元素自动平移的效果 思路很简单 根据listView 的滑动距离去计算图片和文字应该平移 ...

  4. android自定义View学习(一)----创建一个视图类

    创建一个视图类 精心设计的自定义视图与其他精心设计的类非常相似.它使用易于使用的界面封装了一组特定的功能,它可以高效地使用CPU和内存,等等.不过,作为一个设计良好的班级,自定义视图应该: 符合And ...

  5. Android 自定义 圆环,Android自定义view实现圆环效果实例代码

    先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...

  6. android view 渐变动画,Android自定义view渐变圆形动画

    本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...

  7. 自定义圆形倒计时Android,Android自定义View倒计时圆

    本文实例为大家分享了Android自定义View倒计时圆的具体代码,供大家参考,具体内容如下 创建attr 创建DisplayUtil 类 import android.content.Context ...

  8. android波纹效果弹窗,Android自定义View实现波纹效果

    Android自定义View实现波纹效果 时间:2017-05-27     来源:移动互联网学院 1.引言:随着Android智能手机的普及,Android应用得到了大力支持,而Android应用的 ...

  9. android自定义虚线,Android自定义view的方式绘制虚线

    Android自定义view绘制虚线 最近项目中有个需求,通过自定义view的方式绘制虚线 别的不多说先看一眼效果 这个需求在我们的开发中应该是一个很常见的需求了吧,有人会说有更简单的实现方式,对,但 ...

最新文章

  1. 类的成员和嵌套(建模)
  2. java基础-Eclipse开发工具介绍
  3. unity3d软阴影和硬阴影的原理_Unity3D中两种默认阴影的实现
  4. freemarker跳出循环
  5. 近7万新冠域名一半是钓鱼网站?以色列老牌安全厂商Check Point推出全端保护新战略
  6. 如何在linux下创建一个可运行shell脚本?
  7. jquery异步调用post的一些注意事项
  8. php成品网站安装,PHPweb成品网站安装环境要求和安装方法
  9. 开机时自动运行shell_病毒究竟是怎么自动执行的(上)?
  10. paip.python错误解决24
  11. Mysql 语句执行顺序
  12. 跟着团子学SAP—SAP LTMC基础教程(物料主数据导入示例)
  13. Kata Containers及相关vmm介绍
  14. 设计模式之桥接模式:如何实现抽象协议与不同实现的绑定?
  15. 关于3dmax模型导入到u3d中时,坐标会旋转的问题
  16. Windows7自带截图工具没法保存
  17. 司空见惯 - 天黑请闭眼
  18. 即期信用证和远期信用证
  19. Laxcus大数据操作系统2.0(5)- 第二章 数据组织
  20. 只因小黑子的jquery入土过程

热门文章

  1. utf8mb4_0900_ai_ci
  2. ray-tune 笔记 核心概念
  3. 在Lenovo台式机Win7系统基础上直接安装Ubuntu18.04遇到的问题及对策
  4. 【云创大会讲师访谈】如何打造游戏研发“流水线”?谷得技术总监陈镇洪是这么说的...
  5. 【活动预告】Hi,游戏开发者,这有一份您的邀请函
  6. strcpy、wcscpy与_tcscpy关系 strcpy_s与strcpy比较
  7. 启明智显分享|WIFI蓝牙智能猫眼门铃应用方案
  8. lasagne embedding layer理解
  9. 自考《操作系统》总结(持续更新)
  10. <img>的title和alt有什么区别