zgh_branch
parent
0cbce69873
commit
2335752a76
@ -0,0 +1,116 @@
|
||||
package com.example.sleep;
|
||||
|
||||
import static com.example.sleep.database.GetRecord.getRecord;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.sleep.database.GetRecord;
|
||||
import com.example.sleep.database.RecordBean;
|
||||
import com.example.sleep.drawChart.DrawPieChart;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 结束记录的界面
|
||||
*/
|
||||
public class AfterSleepReport extends Activity {
|
||||
|
||||
//这些变量存储对布局文件中的UI元素的引用
|
||||
RelativeLayout background; //背景图片布局
|
||||
TextView mTime; //显示总的睡眠时间的文字视图
|
||||
TextView mStartTime; //显示开始睡眠时间的文字视图
|
||||
TextView mStopTime; //显示结束睡眠时间的文字视图
|
||||
PieChart mPieChart; //用于显示深度、浅度和REM睡眠时间的饼状图
|
||||
TextView mDeep; //显示深度睡眠时间的文字视图
|
||||
TextView mSwallow; //显示浅度睡眠时间的文字视图
|
||||
TextView mDream; //显示睡眠时间的文字视图
|
||||
DrawPieChart mDrawPieChart; //显示睡眠信息图
|
||||
|
||||
private RecordBean mRecord;
|
||||
private ImageView sleepReport;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
//调用父类的方法,设置默认的布局文件
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.aftersleep);
|
||||
|
||||
//初始化各个UI组件
|
||||
background = findViewById(R.id.aftersleep_background);
|
||||
findViewById(R.id.btn_AfterSleep).setOnClickListener(v -> {
|
||||
finish(); //当点击"完成"按钮时,结束当前活动
|
||||
});
|
||||
sleepReport = findViewById(R.id.report);
|
||||
mPieChart = findViewById(R.id.mPiechart);
|
||||
mTime = findViewById(R.id.sleepTime);
|
||||
mStartTime = findViewById(R.id.startTime);
|
||||
mStopTime = findViewById(R.id.stopTime);
|
||||
mDeep = findViewById(R.id.deep);
|
||||
mSwallow = findViewById(R.id.swallow);
|
||||
mDream = findViewById(R.id.dream);
|
||||
|
||||
//随机背景
|
||||
int[] array = {R.drawable.bg_1, R.drawable.bg_4, R.drawable.bg_5};
|
||||
Random rnd = new Random();
|
||||
int index = rnd.nextInt(3);
|
||||
Resources resources = getBaseContext().getResources();
|
||||
Drawable cur = resources.getDrawable(array[index]);
|
||||
background.setBackground(cur);
|
||||
//long recordId = this.getIntent().getLongExtra("recordId", 0);
|
||||
//获取最新的睡眠记录
|
||||
GetRecord mGetRecord = getRecord();
|
||||
mRecord = mGetRecord.getLatestRecord();
|
||||
initView();
|
||||
|
||||
}
|
||||
|
||||
//设置文本
|
||||
protected void initView() {
|
||||
if (mRecord != null) {
|
||||
mStartTime.setText(String.format(getResources().getString(R.string.sleep_time), mRecord.getStartTime()));
|
||||
mStopTime.setText(String.format(getResources().getString(R.string.get_up_time), mRecord.getEndTime()));
|
||||
mTime.setText(String.format(Locale.getDefault(), "时长 %02d:%02d",
|
||||
mRecord.getTotalTime() / 60, mRecord.getTotalTime() % 60));
|
||||
mDeep.setText(String.format(Locale.getDefault(), "深度睡眠 %02d:%02d",
|
||||
mRecord.getDeepTime() / 60, mRecord.getDeepTime() % 60));
|
||||
mSwallow.setText(String.format(Locale.getDefault(), "浅层睡眠 %02d:%02d",
|
||||
mRecord.getSwallowTime() / 60, mRecord.getSwallowTime() % 60));
|
||||
mDream.setText(String.format(Locale.getDefault(), "醒/梦 %02d:%02d",
|
||||
mRecord.getAwakeTime() / 60, mRecord.getAwakeTime() % 60));
|
||||
mDrawPieChart = new DrawPieChart(mPieChart, mRecord, getResources());
|
||||
} else {
|
||||
Toast.makeText(this, "数据错误", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
//返回键效果
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
Intent i = new Intent().setClass(AfterSleepReport.this, MainScreen.class);
|
||||
AfterSleepReport.this.startActivity(i);
|
||||
AfterSleepReport.this.finish();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.example.sleep;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
|
||||
public class AlarmReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// 获取默认的闹钟铃声的URI
|
||||
// Uri alarmTone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
|
||||
// Uri alarmTone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||
Uri alarmTone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
|
||||
Log.e("闹铃:","received: " +alarmTone.toString());
|
||||
// 检查权限
|
||||
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
// 使用Ringtone来播放声音
|
||||
Ringtone ringtone = RingtoneManager.getRingtone(App.mContext, alarmTone);
|
||||
if (ringtone != null) {
|
||||
Log.e("闹铃:","ringtone is playing");
|
||||
ringtone.play();
|
||||
} else {
|
||||
Log.e("闹铃:","ringtone is null");
|
||||
}
|
||||
} else {
|
||||
// 如果没有权限,可以选择播放内置的声音或其他方式提醒用户
|
||||
Log.e("闹铃:","no premission");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package com.example.sleep;
|
||||
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
|
||||
public class SleepFragment extends Fragment {
|
||||
private Button startSleep;
|
||||
private FragmentActivity activity;
|
||||
private Button alarmTime;
|
||||
private Calendar calendar;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// 在这里设置 SleepFragment 的布局,例如从 XML 文件中加载
|
||||
View view = inflater.inflate(R.layout.fragment_sleep, container, false);
|
||||
initView(view);
|
||||
initListener();
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
// 在这里获取关联的Activity上下文
|
||||
activity = getActivity();
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
startSleep.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Toast.makeText(App.mContext, "开始记录!", Toast.LENGTH_SHORT).show();
|
||||
Intent i = new Intent();
|
||||
i.setClass(App.mContext, SleepMonitoringScreen.class);
|
||||
activity.startActivity(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
public void initView(View view) {
|
||||
ImageView mImageText;
|
||||
mImageText = view.findViewById(R.id.imageText);
|
||||
startSleep = view.findViewById(R.id.btn_start);
|
||||
alarmTime = view.findViewById(R.id.timeBtn);
|
||||
alarmTime.setText("我将会在" + " 00:00 " + "醒来");
|
||||
alarmTime.setOnClickListener(new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
new TimePickerDialog(getActivity(), new TimePickerDialog.OnTimeSetListener() {
|
||||
@Override
|
||||
public void onTimeSet(TimePicker arg0, int h, int m) {
|
||||
MySharedPreferences.saveTime(App.mContext,h,m);
|
||||
//更新按钮上的时间
|
||||
alarmTime.setText("我将会在 " + formatTime(h, m) + " " + "醒来");
|
||||
//设置日历的时间,主要是让日历的年月日和当前同步
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
//设置日历的小时和分钟
|
||||
calendar.set(Calendar.HOUR_OF_DAY, h);
|
||||
calendar.set(Calendar.MINUTE, m);
|
||||
//将秒和毫秒设置为0
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
}
|
||||
}, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true).show();
|
||||
}
|
||||
});
|
||||
//设置随机背景
|
||||
int[] array = {R.drawable.main_bg_1, R.drawable.main_bg_2, R.drawable.main_bg_3,
|
||||
R.drawable.main_bg_4, R.drawable.main_bg_5, R.drawable.main_bg_6};
|
||||
Random rnd = new Random();
|
||||
int index = rnd.nextInt(6);
|
||||
Resources resources = getActivity().getResources();
|
||||
Drawable cur = resources.getDrawable(array[index]);
|
||||
mImageText.setBackground(cur);
|
||||
}
|
||||
|
||||
public String formatTime(int h, int m) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
if (h < 10) {
|
||||
buf.append("0" + h);
|
||||
} else {
|
||||
buf.append(h);
|
||||
}
|
||||
buf.append(" : ");
|
||||
if (m < 10) {
|
||||
buf.append("0" + m);
|
||||
} else {
|
||||
buf.append(m);
|
||||
}
|
||||
setAlarm(getActivity(),h,m);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public void setAlarm(Context context, int h, int m) {
|
||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
Intent intent = new Intent(context, AlarmReceiver.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.HOUR_OF_DAY, h);
|
||||
calendar.set(Calendar.MINUTE, m);
|
||||
|
||||
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.example.sleep.drawChart;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.LimitLine;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.example.sleep.R;
|
||||
import com.example.sleep.database.RecordBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class DrawLineChart {
|
||||
private LineChart mLineChart;
|
||||
private RecordBean mRecord;
|
||||
private Resources mResources;
|
||||
private ArrayList<Integer> times;
|
||||
private ArrayList<Float> sleepDetails;
|
||||
private List<Entry> entries = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 绘制折线图
|
||||
*
|
||||
* @param lineChart 折线图元素
|
||||
* @param mRecord 睡眠记录
|
||||
* @param mResources 绘图资源
|
||||
*/
|
||||
public DrawLineChart(LineChart lineChart, RecordBean mRecord, Resources mResources) {
|
||||
mLineChart = lineChart;
|
||||
mLineChart.setDrawBorders(false);
|
||||
mLineChart.setNoDataText("睡眠时间太短啦!没有足够数据!");
|
||||
mLineChart.setNoDataTextColor(Color.WHITE);
|
||||
mLineChart.setDrawGridBackground(true);
|
||||
mLineChart.setGridBackgroundColor(mResources.getColor(R.color.transparent_gray));
|
||||
mLineChart.setDragEnabled(true);
|
||||
mLineChart.animateX(1000);
|
||||
mLineChart.setScaleEnabled(true);
|
||||
mLineChart.setPinchZoom(true);
|
||||
mLineChart.getDescription().setEnabled(false);
|
||||
//画折线图
|
||||
if (mRecord.getDrawChart()) {
|
||||
this.mResources = mResources;
|
||||
this.mRecord = mRecord;
|
||||
readRecordDetails();
|
||||
drawChart();
|
||||
} else {
|
||||
mLineChart.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRecord(RecordBean mRecord) {
|
||||
this.mRecord = mRecord;
|
||||
if (mRecord.getDrawChart()) {
|
||||
readRecordDetails();
|
||||
drawChart();
|
||||
} else {
|
||||
mLineChart.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void readRecordDetails() {
|
||||
String[] arr = mRecord.getSleepDetail().split(" ");
|
||||
String[] buf;
|
||||
for (String e : arr) {
|
||||
buf = e.split(",");
|
||||
entries.add(new Entry(Integer.parseInt(buf[0]), Float.parseFloat(buf[1])));
|
||||
}
|
||||
}
|
||||
|
||||
private void drawChart() {
|
||||
// 创建线性数据集并设置属性
|
||||
LineDataSet lineDataSet = new LineDataSet(entries, "");
|
||||
lineDataSet.setColor(mResources.getColor(R.color.Pie_Yellow));
|
||||
lineDataSet.setLineWidth(1.6f);
|
||||
lineDataSet.setDrawCircles(false);
|
||||
lineDataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
|
||||
// 设置线性图数据并绘制
|
||||
LineData data = new LineData(lineDataSet);
|
||||
data.setDrawValues(false);
|
||||
|
||||
// 设置X轴属性
|
||||
XAxis xAxis = mLineChart.getXAxis();
|
||||
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||
xAxis.setGranularity(1f);
|
||||
xAxis.setLabelCount(8, false);
|
||||
xAxis.setTextColor(Color.WHITE);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setLabelRotationAngle(0);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
int IValue = (int) value;
|
||||
return String.format(Locale.getDefault(), "%02d:%02d", IValue % 1440 / 60, IValue % 60);
|
||||
}
|
||||
});
|
||||
|
||||
// 设置左侧Y轴属性
|
||||
YAxis leftYAxis = mLineChart.getAxisLeft();
|
||||
leftYAxis.setEnabled(true);
|
||||
leftYAxis.setDrawGridLines(false);
|
||||
leftYAxis.setAxisMinimum(0);
|
||||
leftYAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
// 设置限制线并添加到左侧Y轴
|
||||
LimitLine limitLine = new LimitLine(0.37f, "深度睡眠");
|
||||
limitLine.setLineColor(mResources.getColor(R.color.Pie_Green));
|
||||
limitLine.setTextColor(mResources.getColor(R.color.Pie_Green));
|
||||
leftYAxis.addLimitLine(limitLine);
|
||||
|
||||
LimitLine limitLine1 = new LimitLine(0.8f, "浅层睡眠");
|
||||
limitLine1.setLineColor(mResources.getColor(R.color.Pie_Blue));
|
||||
limitLine1.setTextColor(mResources.getColor(R.color.Pie_Blue));
|
||||
leftYAxis.addLimitLine(limitLine1);
|
||||
|
||||
// 设置图例并绘制线性图
|
||||
Legend legend = mLineChart.getLegend();
|
||||
legend.setEnabled(false);
|
||||
|
||||
mLineChart.setData(data);
|
||||
mLineChart.invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,106 @@
|
||||
package com.example.sleep.drawChart;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.formatter.PercentFormatter;
|
||||
import com.example.sleep.R;
|
||||
import com.example.sleep.database.RecordBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DrawPieChart {
|
||||
|
||||
private PieChart mPieChart;
|
||||
private RecordBean mRecord;
|
||||
private Resources mResources;
|
||||
// 构造函数,设置饼状图的一些属性
|
||||
/**
|
||||
* 绘制饼状图
|
||||
* @param pieChart 饼状图的对象
|
||||
* @param mRecord 睡眠记录
|
||||
* @param mResources 资源实例
|
||||
*/
|
||||
public DrawPieChart(PieChart pieChart, RecordBean mRecord, Resources mResources) {
|
||||
mPieChart = pieChart;
|
||||
mPieChart.setNoDataText("睡眠时间太短啦!没有足够数据!");
|
||||
mPieChart.setNoDataTextColor(Color.WHITE);
|
||||
//画空心饼状图
|
||||
if (mRecord.getDrawChart()) {
|
||||
this.mResources = mResources;
|
||||
this.mRecord = mRecord;
|
||||
drawChart();
|
||||
} else {
|
||||
mPieChart.clear();
|
||||
}
|
||||
}
|
||||
// 设置睡眠记录
|
||||
public void setRecord(RecordBean mRecord) {
|
||||
this.mRecord = mRecord;
|
||||
if (mRecord.getDrawChart()) {
|
||||
drawChart();
|
||||
} else {
|
||||
mPieChart.clear();
|
||||
}
|
||||
}
|
||||
// 绘制饼状图
|
||||
private void drawChart() {
|
||||
mPieChart.setCenterText("您的睡眠状态");
|
||||
mPieChart.setCenterTextColor(Color.WHITE);
|
||||
mPieChart.setUsePercentValues(true);
|
||||
mPieChart.getDescription().setEnabled(false);
|
||||
mPieChart.setExtraOffsets(10, 10, 10, 5);
|
||||
mPieChart.setDrawCenterText(true);
|
||||
mPieChart.setDrawHoleEnabled(true);
|
||||
mPieChart.setTransparentCircleColor(Color.WHITE);
|
||||
mPieChart.setTransparentCircleAlpha(110);
|
||||
mPieChart.setHoleRadius(58f);
|
||||
mPieChart.setHoleColor(Color.TRANSPARENT);
|
||||
mPieChart.setTransparentCircleRadius(61f);
|
||||
mPieChart.setRotationAngle(0);
|
||||
mPieChart.setRotationEnabled(true);
|
||||
mPieChart.setHighlightPerTapEnabled(false);
|
||||
// 创建包含睡眠状态数据的 PieEntry 对象列表
|
||||
ArrayList<PieEntry> entries = new ArrayList<>();
|
||||
entries.add(new PieEntry(mRecord.getDeepTime(), "深度睡眠"));
|
||||
entries.add(new PieEntry(mRecord.getSwallowTime(), "浅层睡眠"));
|
||||
entries.add(new PieEntry(mRecord.getAwakeTime(), "醒/梦"));
|
||||
// 设置饼状图数据集
|
||||
PieDataSet dataSet = new PieDataSet(entries, "");
|
||||
dataSet.setSliceSpace(3f);
|
||||
dataSet.setSelectionShift(5f);
|
||||
// 设置图例
|
||||
mPieChart.setEntryLabelColor(Color.WHITE);
|
||||
mPieChart.setEntryLabelTextSize(12f);
|
||||
Legend l = mPieChart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
l.setXEntrySpace(7f);
|
||||
l.setYEntrySpace(0f);
|
||||
l.setYOffset(0f);
|
||||
l.setTextColor(Color.WHITE);
|
||||
// 设置颜色
|
||||
ArrayList<Integer> colors = new ArrayList<>();
|
||||
colors.add(mResources.getColor(R.color.Pie_Green));
|
||||
colors.add(mResources.getColor(R.color.Pie_Blue));
|
||||
colors.add(mResources.getColor(R.color.Pie_Yellow));
|
||||
dataSet.setColors(colors);
|
||||
// 设置饼状图数据并进行动画效果的设置
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueFormatter(new PercentFormatter());
|
||||
data.setValueTextSize(11f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
mPieChart.setData(data);
|
||||
mPieChart.highlightValues(null);
|
||||
mPieChart.animateY(1400, Easing.EasingOption.EaseInOutQuad);
|
||||
mPieChart.invalidate();
|
||||
}
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
package com.example.sleep.drawChart;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class SimpleLineChart extends View {
|
||||
//View 的宽和高
|
||||
private int mWidth, mHeight;
|
||||
private int yInterval;
|
||||
//Y轴字体的大小
|
||||
private float mYAxisFontSize = 24;
|
||||
|
||||
//线的颜色
|
||||
private int mLineColor = Color.parseColor("#00BCD4");
|
||||
|
||||
//线条的宽度
|
||||
private float mStrokeWidth = 8.0f;
|
||||
|
||||
//点的集合
|
||||
private HashMap<Integer, Double> mPointMap;
|
||||
|
||||
//点的半径
|
||||
private float mPointRadius = 10;
|
||||
|
||||
//没有数据的时候的内容
|
||||
private String mNoDataMsg = "no data";
|
||||
|
||||
//X轴的文字
|
||||
private String[] mXAxis = {"aa"};
|
||||
|
||||
//Y轴的文字
|
||||
private String[] mYAxis = {"bb"};
|
||||
|
||||
public SimpleLineChart(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SimpleLineChart(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SimpleLineChart(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 (widthMode == MeasureSpec.EXACTLY) {
|
||||
mWidth = widthSize;
|
||||
}else if(widthMode == MeasureSpec.AT_MOST){
|
||||
throw new IllegalArgumentException("width must be EXACTLY,you should set like android:width=\"200dp\"");
|
||||
}
|
||||
|
||||
if (heightMode == MeasureSpec.EXACTLY) {
|
||||
mHeight = heightSize;
|
||||
}else if(widthMeasureSpec == MeasureSpec.AT_MOST){
|
||||
|
||||
throw new IllegalArgumentException("height must be EXACTLY,you should set like android:height=\"200dp\"");
|
||||
}
|
||||
|
||||
setMeasuredDimension(mWidth, mHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
|
||||
if(mXAxis.length==0||mYAxis.length==0){
|
||||
throw new IllegalArgumentException("X or Y items is null");
|
||||
}
|
||||
//画坐标线的轴
|
||||
Paint axisPaint = new Paint();
|
||||
axisPaint.setTextSize(mYAxisFontSize);
|
||||
axisPaint.setColor(Color.parseColor("#3F51B5"));
|
||||
|
||||
if (mPointMap == null || mPointMap.size() == 0) {
|
||||
int textLength = (int) axisPaint.measureText(mNoDataMsg);
|
||||
canvas.drawText(mNoDataMsg, mWidth/2 - textLength/2, mHeight/2, axisPaint);
|
||||
} else {
|
||||
//画 Y 轴
|
||||
|
||||
|
||||
//存放每个Y轴的坐标
|
||||
double[] yPoints = new double[mYAxis.length];
|
||||
|
||||
|
||||
//计算Y轴 每个刻度的间距
|
||||
yInterval = (int) ((mHeight - mYAxisFontSize - 2) / (mYAxis.length));
|
||||
|
||||
//测量Y轴文字的高度 用来画第一个数
|
||||
Paint.FontMetrics fm = axisPaint.getFontMetrics();
|
||||
int yItemHeight = (int) Math.ceil(fm.descent - fm.ascent);
|
||||
|
||||
for (int i = 0; i < mYAxis.length; i++) {
|
||||
canvas.drawText(mYAxis[i], 0, mYAxisFontSize + i * yInterval, axisPaint);
|
||||
yPoints[i] = (int) (mYAxisFontSize + i * yInterval);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//画 X 轴
|
||||
|
||||
//x轴的刻度集合
|
||||
int[] xPoints = new int[mXAxis.length];
|
||||
|
||||
//计算Y轴开始的原点坐标
|
||||
int xItemX = (int) axisPaint.measureText(mYAxis[1]);
|
||||
|
||||
//X轴偏移量
|
||||
int xOffset = 50;
|
||||
//计算x轴 刻度间距
|
||||
int xInterval = (int) ((mWidth - xOffset) / (mXAxis.length));
|
||||
//获取X轴刻度Y坐标
|
||||
int xItemY = (int) (mYAxisFontSize + mYAxis.length * yInterval);
|
||||
|
||||
for (int i = 0; i < mXAxis.length; i++) {
|
||||
canvas.drawText(mXAxis[i], i * xInterval + xItemX + xOffset, xItemY, axisPaint);
|
||||
xPoints[i] = (int) (i * xInterval + xItemX + axisPaint.measureText(mXAxis[i]) / 2 + xOffset + 10);
|
||||
// Log.e("wing", xPoints[i] + "");
|
||||
}
|
||||
|
||||
|
||||
//画点
|
||||
Paint pointPaint = new Paint();
|
||||
|
||||
pointPaint.setColor(mLineColor);
|
||||
|
||||
Paint linePaint = new Paint();
|
||||
|
||||
linePaint.setColor(mLineColor);
|
||||
linePaint.setAntiAlias(true);
|
||||
//设置线条宽度
|
||||
linePaint.setStrokeWidth(mStrokeWidth);
|
||||
pointPaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
|
||||
for (int i = 0; i < mXAxis.length; i++) {
|
||||
if (mPointMap.get(i) == null) {
|
||||
throw new IllegalArgumentException("PointMap has incomplete data!");
|
||||
}
|
||||
|
||||
//画点
|
||||
canvas.drawCircle(xPoints[i], (float)(yPoints[5]+(yPoints[0]-yPoints[5])*mPointMap.get(i)), mPointRadius, pointPaint);
|
||||
if (i > 0) {
|
||||
canvas.drawLine(xPoints[i - 1], (float)(yPoints[5]+(yPoints[0]-yPoints[5])*mPointMap.get(i - 1)), xPoints[i], (float)(yPoints[5]+(yPoints[0]-yPoints[5])*mPointMap.get(i)), linePaint);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置map数据
|
||||
* @param data
|
||||
*/
|
||||
public void setData(HashMap<Integer,Double> data){
|
||||
mPointMap = data;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Y轴文字
|
||||
* @param yItem
|
||||
*/
|
||||
public void setYItem(String[] yItem){
|
||||
mYAxis = yItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置X轴文字
|
||||
* @param xItem
|
||||
*/
|
||||
public void setXItem(String[] xItem){
|
||||
mXAxis = xItem;
|
||||
}
|
||||
|
||||
public void setLineColor(int color){
|
||||
mLineColor = color;
|
||||
invalidate();
|
||||
}
|
||||
}
|
Loading…
Reference in new issue