1.MainActivity.java
package fanxiaoli.round;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//数据
List<Integer> datas = new ArrayList<Integer>();
datas.add(66);
datas.add(77);
datas.add(66);
datas.add(88);
datas.add(64);
datas.add(20);
datas.add(44);
datas.add(22);
datas.add(99);
datas.add(35);
datas.add(35);
datas.add(66);
LineChartView lineChartView = (LineChartView) findViewById(R.id.lineCharView);
//给折线图设置数据,和颜色
lineChartView.setDatas(datas, Color.YELLOW);
}
//关闭页面
public void close(View view) {
finish();
}
}
2.LineChartView.java
package fanxiaoli.round;
/**
* Created by fanxiaoli on 2017/3/23.
*/
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* 折线图
*/
public class LineChartView extends View {
private int mWidth;
private int mHeight;
private List<Integer> mDatas = new ArrayList<Integer>();
private int paintColors;
private Paint mPaint;
public LineChartView(Context context) {
this(context, null);
}
public LineChartView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LineChartView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* 设置数据
*
* @param datas 集合里面还有每条线的集合数据
* @param colors 表示线的颜色集合
*/
public void setDatas(List<Integer> datas, int colors) {
if (datas != null && datas.size() != 0) {
mDatas.clear();
mDatas.addAll(datas);
paintColors = colors;
//重绘视图
postInvalidate();
}
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeWidth(2f);
mPaint.setColor(Color.GREEN);
setBackgroundColor(Color.BLACK);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDatas != null) { //传人数据后再实现重绘
mPaint.setColor(paintColors);
//画底下和顶上的线
drawBackGroudLines(canvas);
//画左边的标尺线
DrawLineLeft(canvas);
//画下边的标尺线
drawLineAndTextButtom(canvas);
//绘制上面的文字提示
drawTextTop(canvas);
} else {
canvas.drawText("正在绘制页面", 100, 100, mPaint);
}
}
/**
* 绘制底下的横线和文字
*
* @param canvas
*/
private void drawLineAndTextButtom(Canvas canvas) {
canvas.drawLine(0, mHeight - 50, mWidth, mHeight - 50, mPaint);
//直线底下的文字
for (int i = 0; i < 24; i++) {
String textString = i + ":00";
mPaint.setTextSize(10);
canvas.drawText(textString, 40 + i * (mWidth / 24) - 10, mHeight - 30, mPaint);
//在文字上面画一条小直线
canvas.drawLine(40 + i * (mWidth / 24), mHeight - 50, 40 + i * (mWidth / 24), mHeight - 70, mPaint);
}
}
/**
* 绘制左边的坐标线
*
* @param canvas
*/
private void DrawLineLeft(Canvas canvas) {
mPaint.setStyle(Paint.Style.FILL);//实心
canvas.drawLine(50, 0, 50, mHeight, mPaint);
//直线边上的文字
for (int i = 0; i < 7; i++) {
String textString = i * 30 + "";
mPaint.setTextSize(20);
canvas.drawText(textString, 10, mHeight - i * 30 * (mWidth / 200), mPaint);
}
}
/**
* 绘制上面的文字提示
*
* @param canvas
*/
private void drawTextTop(Canvas canvas) {
drawLineChart(canvas, mDatas);
//画文字
mPaint.setTextSize(60);
canvas.drawText("心跳的频率", 50, 50, mPaint);
}
/**
* 传人点的集合数据,绘制线条
*
* @param canvas
* @param datas
*/
private void drawLineChart(Canvas canvas, List<Integer> datas) {
int size = datas.size();
if (size != 0 && size != 1) {
float[] points = new float[size * 4];
float pointWidth = (float) mWidth / (float) (size - 1);
float pointHeight = (float) mHeight / 255f;
// 起点和落点的 x,y 坐标!
//Y方向其实是向下偏移了(mHeight-2y)的长度,也就是在原来的基础上添加偏移量的值,即可得到目的的Y
//比如(x,y)---》(x,mHeight-y)
//根据API限定距离顶部是y的距离,目的是距离底部是y的距离,而距离顶部是(mHeight-y)的距离,是不是偏移了(mHeight-2y)的长度!
// (mHeight-2y)+y= mHeight-y;
float startX = -pointWidth;
float startY = mHeight - datas.get(0) * pointHeight;
float stopX, stopY;
for (int i = 0; i < datas.size(); i++) {
stopX = startX + pointWidth; //x轴的坐标每次添加一个单位长度。
stopY = mHeight - datas.get(i) * pointHeight;
// 将起点和落点加入集合
addPoint(points, i, startX, startY, stopX, stopY);
// 将落点的值记录下来作为下一次的起点
startX = stopX;
startY = stopY;
}
canvas.drawLines(points, mPaint);
}
}
/**
* 将起点和落点加入集合
*
* @param points 添加到哪个集合,所有点坐标的最终数组
* @param i 添加的是哪个点组合的数据,代表的是点的个数
* @param startX 起点 X 坐标
* @param startX 起点 Y 坐标
* @param stopX 落点 X 坐标
* @param stopY 落点 Y 坐标
*/
private void addPoint(float[] points, int i, float startX, float startY, float stopX, float stopY) {
int index = i * 4;
// 起点
points[index] = startX;
points[index + 1] = startY;
// 落点
points[index + 2] = stopX;
points[index + 3] = stopY;
}
/**
* //绘制底部和顶部的线
*/
private void drawBackGroudLines(Canvas canvas) {
canvas.drawLine(0, 0, mWidth, 0, mPaint);
canvas.drawLine(0, mHeight, mWidth, mHeight, mPaint);
}
/**
* 得到View的宽度和高度
*
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.e("TAG2", "onSizeChanged");
mWidth = getWidth();
mHeight = getHeight();
}
}
3.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<fanxiaoli.round.LineChartView
android:layout_width="match_parent"
android:layout_height="400dp"
android:id="@+id/lineCharView"
/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="关闭"
android:onClick="close"
/>
</LinearLayout>