安卓实现生物节律绘制学习笔记

这个简单的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<Integer> 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<Integer> 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,进行绘图

@Override
        protected 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");
    @Override
    protected 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() {
            @Override
            public 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组件)。

@Override
    protected 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() {

        @Override
        public 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<double[]> data = new ArrayList<>();
            List<Integer> 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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值