安卓实现生物节律绘制学习笔记
这个简单的demo需理解掌握绘制曲线方法、生物节律算法、调用日期控件传递数据即可。
具体实现展示图:
界面自动显示的是当前的日期,为最中间的红线:
可点击更换日期按钮,触动对话框显示日期,对日期进行更改(日期为安卓自带控件):
更改日期后会更新绘图:
具体实现
1.绘制曲线,此处为在github中下载的绘图源码,在此源码的基础上进行修改。在安卓工程文件中定义为CustomCurveChat.java,以下是代码分步描述:
①安卓的绘图继承View,并重写它的onDraw( Canvas canvas)。
public class CustomCurveChart extends View {
②对绘制曲线的一些需要值和画笔方法进行声明。
// 坐标单位private String[] xLabel;private String[] yLabel;// 曲线数据private List<double[]> dataList;private List colorList;private boolean showValue;// 默认边距private int margin = 20;// 距离左边偏移量private int marginX = 30;// 原点坐标private int xPoint;private int yPoint;// X,Y轴的单位长度private int xScale;private int yScale;// 画笔private Paint paintAxes;private Paint paintCoordinate;private Paint paintTable;private Paint paintCurve;private Paint paintRectF;private Paint paintValue;private Paint paintToday;
③定义方法(?),获取相关资源。
Context类:通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息等。
public CustomCurveChart(Context context, String[] xLabel, String[] yLabel, List<double[]> dataList, List colorList, boolean showValue) {super(context);this.xLabel = xLabel;this.yLabel = yLabel;this.dataList = dataList;this.colorList = colorList;this.showValue = showValue;}public CustomCurveChart(Context context) {super(context);}
④初始化数据值和画笔。
/*** 初始化数据值和画笔*/public void init() {xPoint = margin + marginX;yPoint = this.getHeight() - margin;xScale = (this.getWidth() - 2 * margin - marginX) / (xLabel.length - 1);yScale = (this.getHeight() - 2 * margin) / (yLabel.length - 1);paintAxes = new Paint();paintAxes.setStyle(Paint.Style.STROKE);paintAxes.setAntiAlias(true);paintAxes.setDither(true);paintAxes.setColor(ContextCompat.getColor(getContext(), R.color.color14));paintAxes.setStrokeWidth(4);paintCoordinate = new Paint();paintCoordinate.setStyle(Paint.Style.STROKE);paintCoordinate.setDither(true);paintCoordinate.setAntiAlias(true);paintCoordinate.setColor(ContextCompat.getColor(getContext(), R.color.color14));paintCoordinate.setTextSize(15);...//省略
}
⑤重写onDraw,进行绘图
@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(ContextCompat.getColor(getContext(), R.color.color1));init();drawTable(canvas, paintTable);drawAxesLine(canvas, paintAxes);drawCoordinate(canvas, paintCoordinate);drawToday(canvas,paintToday);for (int i = 0; i < dataList.size(); i++) {System.out.println();drawCurve(canvas, paintCurve, dataList.get(i), colorList.get(i));if (showValue) {drawValue(canvas, paintRectF, dataList.get(i), colorList.get(i));}}}
⑥定义绘制方法
/*** 绘制坐标轴*/
private void drawAxesLine(Canvas canvas, Paint paint){}/*** 绘制表格*/
private void drawTable(Canvas canvas, Paint paint){}
/*** 绘制今日 中间竖线*/
private void drawToday(Canvas canvas, Paint paint){}
...//省略
2.主Activity: RhythmActivity.java
①定义一个线性布局用于绘制曲线图,一个按钮点击触发显示对话框,全局变量用于存储日期变量,展示选择日期和显示今日数值的方法,初始化绘图的方法。
public class RhythmActivity extends AppCompatActivity {private LinearLayout customCurveChart1;int mYear, mMonth, mDay;Button btn;TextView dateDisplay;final int DATE_DIALOG = 1;SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd");@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_rhythm);customCurveChart1 = (LinearLayout) findViewById(R.id.customCurveChart1);btn = (Button) findViewById(R.id.change_date);dateDisplay = (TextView) findViewById(R.id.today_date);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showDialog(DATE_DIALOG);}});final Calendar ca = Calendar.getInstance();mYear = ca.get(Calendar.YEAR);mMonth = ca.get(Calendar.MONTH);mDay = ca.get(Calendar.DAY_OF_MONTH);display();String birth = set_birthDay();initCurveChart1(birth);}
②重写onCreateDialog,当被触发时id为1,创建DatePickerDialog对象(DatePicker日历UI组件)。
@Overrideprotected Dialog onCreateDialog(int id) {switch (id) {case DATE_DIALOG:return new DatePickerDialog(this, mdateListener, mYear, mMonth, mDay);}return null;}
③设置展示日期的格式,显示当前日期或修改后的日期。
public void display() {Calendar curDate = Calendar.getInstance();curDate.set(mYear, mMonth, mDay);String date = formatter.format(curDate.getTime());dateDisplay.setText(date);}
④更改日期数据获取和更新。
private DatePickerDialog.OnDateSetListener mdateListener = new DatePickerDialog.OnDateSetListener() {@Overridepublic void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth) {mYear = year;mMonth = monthOfYear;mDay = dayOfMonth;display();String birth1 = set_birthDay();initCurveChart1(birth1);}};
⑤初始化曲线图数据,此处需要用到计算生物节律以及绘制的算法。
智力周期33天,情绪周期28天,体力周期23天。计算从出生到目前日期的总天数,再计算各总天数除以周期的余数,最后对应绘制正弦曲线。
此处是以目前日期为中心,往前和后各延15天,总共绘制31天的图。
主要算法:
private void initCurveChart1(String birthday) {double[] physical = new double [31];double[] mood = new double [31];double[] brains = new double [31];String[] xLabel = new String[31];String[] yLabel = {"0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"};Calendar curDate = Calendar.getInstance();curDate.set(mYear, mMonth, mDay);String date = formatter.format(curDate.getTime());long howDays = 0;howDays = getHowDaysFromBirthday(birthday,date);//Log.v("tag",""+howDays);if (howDays <= 0) {return;}else {for (int i = -15; i<= 15; i++){Calendar calendar = Calendar.getInstance();calendar.set(mYear, mMonth, mDay);int a_physical = (int)(howDays + i) % 23;physical[i+15] = getY(a_physical,23);int a_mood = (int)((howDays + i) % 28);mood[i+15] = getY(a_mood,28);int a_brains = (int)((howDays + i) % 33);brains[i+15] = getY(a_brains,33);calendar.add(Calendar.DATE,+i);xLabel[i+15] = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));calendar.clear();}TextView tvp = (TextView) findViewById(R.id.today_physical);tvp.setText(String.valueOf(savetwoY(physical[15])));TextView tvm = (TextView) findViewById(R.id.today_mood);tvm.setText(String.valueOf(savetwoY(mood[15])));TextView tvb = (TextView) findViewById(R.id.today_brains);tvb.setText(String.valueOf(savetwoY(brains[15])));List data = new ArrayList<>();List color = new ArrayList<>();data.add(brains);color.add(R.color.color13);data.add(mood);color.add(R.color.color14);data.add(physical);color.add(R.color.colorPrimary);customCurveChart1.removeAllViews();customCurveChart1.addView(new CustomCurveChart(this, xLabel, yLabel, data, color, false));}}
计算总天数,正弦函数转换
private long getHowDaysFromBirthday(String from, String to) {if (from == null || to == null || to.equals("") || from.equals("")) {return -1;}try {Date date1 = formatter.parse(from);Date date2 = formatter.parse(to);long howDays = (date2.getTime()-date1.getTime())/(60*60*1000*24);return howDays;} catch (Exception e) {return 0;}}private double getY (int phase, int cycle){double y = Math.sin(2 * Math.PI / cycle * (phase)) * 50 + 50;return y;}
整个项目代码已上传至github:CurveChartTest
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
