自定义折线图
来源:互联网 发布:什么是bim软件 编辑:程序博客网 时间:2024/06/05 23:56
继续来一片简单的自定义View,折线图的自定义。
每天来一篇,进步无极限。愚公移山也要由易到难的,这次就没写xml文件的自定义属性:
public DefineLineView(Context context) { super(context); } public DefineLineView(Context context, AttributeSet attrs) { super(context, attrs); } public DefineLineView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
然后还是重写onMeasure方法:
int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (MeasureSpec.EXACTLY == widthMode) { width = widthSize; } else { throw new IllegalArgumentException("width is exactly mode!"); } if (MeasureSpec.EXACTLY == heightMode) { height = heightSize; } else { throw new IllegalArgumentException("height is exactly mode!"); } setMeasuredDimension(width, height);
由于想省点事,就直接用EXACTLY ,没有去管atmost,无关紧要,
关键在ondraw方法里面比较费事:
@Override protected void onDraw(Canvas canvas) { Paint mPaint = new Paint(); mPaint.setTextSize(textFontSize); mPaint.setColor(Color.RED); /** * 画Y轴 */ int[] pointY = new int[textY.length];//保存y轴文字的坐标 //计算每个刻度的间距 int discY = (int) ((height - textFontSize * textY.length) / textY.length); //测量文字的高度 Paint.FontMetrics fm = mPaint.getFontMetrics(); int yheight = (int) Math.ceil(fm.descent - fm.ascent); for (int i = 0; i < textY.length; i++) { canvas.drawText(textY[i], 0, discY * i + yheight, mPaint); pointY[i] = discY * i + yheight; } /** * 画X轴 */ int[] pointX = new int[textX.length];//保存y轴文字的坐标 int offset = 50; //计算每个刻度的距离 int discX = (int) ((width - textFontSize * textX.length) / textX.length); for (int i = 0; i < textX.length; i++) { canvas.drawText(textX[i], i * discX + textFontSize + offset, height - yheight - offset, mPaint); pointX[i] = (int) (i * discX + textFontSize + offset); } /** * 画点 */ mPaint.setColor(Color.DKGRAY); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); int radious = 10; Paint linePaint = new Paint(); linePaint.setColor(Color.DKGRAY); linePaint.setAntiAlias(true); linePaint.setStrokeWidth(5); for (int i = 0; i < textX.length; i++) { if (mapParams == null) { throw new IllegalArgumentException("map 不能为空"); } canvas.drawCircle(pointX[i], pointY[mapParams.get(i)], radious, mPaint); if (i > 0) { canvas.drawLine(pointX[i - 1], pointY[mapParams.get(i - 1)], pointX[i], pointY[mapParams.get(i)], linePaint); } } }
首先画Y轴,在画Y轴的时候定义了一个数组来保存对应的坐标:
/** * 画Y轴 */ int[] pointY = new int[textY.length];//保存y轴文字的坐标 //计算每个刻度的间距 int discY = (int) ((height - textFontSize * textY.length) / textY.length); //测量文字的高度 Paint.FontMetrics fm = mPaint.getFontMetrics(); int yheight = (int) Math.ceil(fm.descent - fm.ascent); for (int i = 0; i < textY.length; i++) { canvas.drawText(textY[i], 0, discY * i + yheight, mPaint); pointY[i] = discY * i + yheight; }
然后同样画X轴的时候,也要定义一个数组来保存X轴的坐标,
/** * 画X轴 */ int[] pointX = new int[textX.length];//保存y轴文字的坐标 int offset = 50; //计算每个刻度的距离 int discX = (int) ((width - textFontSize * textX.length) / textX.length); for (int i = 0; i < textX.length; i++) { canvas.drawText(textX[i], i * discX + textFontSize + offset, height - yheight - offset, mPaint); pointX[i] = (int) (i * discX + textFontSize + offset); }
下面就是画点,首先在MainActivity里面定义了一个Map来保存要画的点,通过在View设置的方法把Map传进来。
/** * 设置Y轴的数据 * * @param textY */ public void setTextY(String[] textY) { this.textY = textY; } /** * 设置X轴的数据 * * @param textX */ public void setTextX(String[] textX) { this.textX = textX; } /** * 设置Map * * @param mapParams */ public void setMapParams(Map<Integer, Integer> mapParams) { this.mapParams = mapParams; }
然后就开始画点和画折线:
/** * 画点 */ mPaint.setColor(Color.DKGRAY); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); int radious = 10; Paint linePaint = new Paint(); linePaint.setColor(Color.DKGRAY); linePaint.setAntiAlias(true); linePaint.setStrokeWidth(5); for (int i = 0; i < textX.length; i++) { if (mapParams == null) { throw new IllegalArgumentException("map 不能为空"); } canvas.drawCircle(pointX[i], pointY[mapParams.get(i)], radious, mPaint); if (i > 0) { canvas.drawLine(pointX[i - 1], pointY[mapParams.get(i - 1)], pointX[i], pointY[mapParams.get(i)], linePaint); } }
最后在MainActivity里面设置下数据就ok了:
private String[] textY = {"50k", "40k", "30k", "20K", "10k"}; private String[] textX = {"1", "2", "3", "4", "5", "6", "7"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DefineLineView lineView = (DefineLineView) findViewById(R.id.lineView); lineView.setTextY(textY); lineView.setTextX(textX); Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < textX.length; i++) { map.put(i, (int) (Math.random() * 5)); } lineView.setMapParams(map); }
贴一下Xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.shuiai.defineline.DefineLineView android:id="@+id/lineView" android:layout_width="match_parent" android:layout_height="300dp" /></LinearLayout>
贴下View的完整代码:
public class DefineLineView extends View { /** * view的宽 */ private int width; /** * View的高 */ private int height; /** * 存放Y轴文字的数组 */ private String[] textY; /** * 存放X轴文字的数组 */ private String[] textX; /** * 文字大小 */ private float textFontSize = 40; /** * 设置Map * * @param context */ private Map<Integer, Integer> mapParams; public DefineLineView(Context context) { super(context); } public DefineLineView(Context context, AttributeSet attrs) { super(context, attrs); } public DefineLineView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (MeasureSpec.EXACTLY == widthMode) { width = widthSize; } else { throw new IllegalArgumentException("width is exactly mode!"); } if (MeasureSpec.EXACTLY == heightMode) { height = heightSize; } else { throw new IllegalArgumentException("height is exactly mode!"); } setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { Paint mPaint = new Paint(); mPaint.setTextSize(textFontSize); mPaint.setColor(Color.RED); /** * 画Y轴 */ int[] pointY = new int[textY.length];//保存y轴文字的坐标 //计算每个刻度的间距 int discY = (int) ((height - textFontSize * textY.length) / textY.length); //测量文字的高度 Paint.FontMetrics fm = mPaint.getFontMetrics(); int yheight = (int) Math.ceil(fm.descent - fm.ascent); for (int i = 0; i < textY.length; i++) { canvas.drawText(textY[i], 0, discY * i + yheight, mPaint); pointY[i] = discY * i + yheight; } /** * 画X轴 */ int[] pointX = new int[textX.length];//保存y轴文字的坐标 int offset = 50; //计算每个刻度的距离 int discX = (int) ((width - textFontSize * textX.length) / textX.length); for (int i = 0; i < textX.length; i++) { canvas.drawText(textX[i], i * discX + textFontSize + offset, height - yheight - offset, mPaint); pointX[i] = (int) (i * discX + textFontSize + offset); } /** * 画点 */ mPaint.setColor(Color.DKGRAY); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); int radious = 10; Paint linePaint = new Paint(); linePaint.setColor(Color.DKGRAY); linePaint.setAntiAlias(true); linePaint.setStrokeWidth(5); for (int i = 0; i < textX.length; i++) { if (mapParams == null) { throw new IllegalArgumentException("map 不能为空"); } canvas.drawCircle(pointX[i], pointY[mapParams.get(i)], radious, mPaint); if (i > 0) { canvas.drawLine(pointX[i - 1], pointY[mapParams.get(i - 1)], pointX[i], pointY[mapParams.get(i)], linePaint); } } } /** * 设置Y轴的数据 * * @param textY */ public void setTextY(String[] textY) { this.textY = textY; } /** * 设置X轴的数据 * * @param textX */ public void setTextX(String[] textX) { this.textX = textX; } /** * 设置Map * * @param mapParams */ public void setMapParams(Map<Integer, Integer> mapParams) { this.mapParams = mapParams; }}
有木有很简单,很简单。
0 0
- 折线图 自定义折线图 自定义view
- android 自定义折线图
- android 自定义折线图
- android 自定义 折线图
- android 自定义折线图
- android自定义折线图
- 自定义的折线图
- Android自定义折线图
- android 自定义折线图
- android 自定义折线图
- 自定义View--折线图
- android---自定义折线图
- 自定义折线图
- 自定义折线图
- 自定义View折线图
- 自定义折线图
- android 自定义折线图
- 自定义折线图/柱状图
- Ubuntu 16.04中安装Vim 8.0
- ==在对象、基本类型、Integer类中的使用
- 程序员的绘画
- 【c】杨辉三角
- WebSocket的进一步实例
- 自定义折线图
- yii2.0应用介绍
- GITHUB自学系列之一「初识 GITHUB」
- IOS百度地图屏幕坐标与经纬度坐标的转换
- Pattern Matching
- 01作业
- 使用angularjs1.x构建前台开发框架(二)——require的使用
- iOS开发-事件传递与响应者链中的hitTest方法和pointInside方法
- 大整数乘法CPP