【版本】
当前版本号v20231006
版本 | 修改说明 |
---|---|
v20231006 | 初始化版本 |
【实验名称】 实验6.1 开发最近气温变化曲线图界面
【实验目的】
- 掌握 Android 的可视化界面开发
- 掌握 MPAndroidChart 框架
【实验环境】
- 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
- 计算机可以访问互联网。
- 内存:至少6G
- 硬盘:至少空余20G
- JDK 8或以上
- Android Studio
【实验要求】
- 完成以下智能温度采集的气温变化曲线图界面
【实验步骤】
- 在 settings.gradle下添加以下代码,加入
MPAndroidChart
包的仓库地址。
maven { url 'https://jitpack.io' }
- 在
app/build.gradle
内 dependencies 加入以下依赖包。
implementation 'org.litepal.guolindev:core:3.2.3'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
ThermometerActivity
参考代码,请自行完成代码。
package iot.app.smarthome.ui.device;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Description;
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.github.mikephil.charting.formatter.ValueFormatter;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import iot.app.smarthome.R;
public class ThermometerActivity extends AppCompatActivity {
private final static class TempValueFormatter extends ValueFormatter{
@Override
public String getFormattedValue(float v) {
return (int)v+"\u2103";
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thermometer);
LineChart lineChart=findViewById(R.id.lineChart);
List<Entry> list=new ArrayList<>();
//其中两个数字对应的分别是 X轴 Y轴
list.add(new Entry(7.0F,26F));
list.add(new Entry(8.0F,29F));
list.add(new Entry(9.0F,30F));
list.add(new Entry(10.0F,31F));
list.add(new Entry(11.0F,32F));
//设置图表的数据
LineDataSet lineDataSet=new LineDataSet(list,"最近气温变化");
LineData lineData=new LineData(lineDataSet);
lineData.setValueFormatter(new TempValueFormatter());
lineChart.setData(lineData);
//设置图表描述
Description description=new Description();
description.setText("最近气温变化");
lineChart.setDescription(description);
//获取 X 轴
XAxis xAxis=lineChart.getXAxis();
//设置 X 轴在底部
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setLabelCount(list.size(), false);// 强制设置标签个数
xAxis.setGranularity(1f);//设置X轴刻度间距
//设置 X 轴的格式化显示内容
xAxis.setValueFormatter(new ValueFormatter() { //X轴自定义坐标
@Override
public String getFormattedValue(float v) {
//TODO:请完善此处代码,返回时间格式 h:mm
}
});
//获取左 Y 轴
YAxis yLeftAxis=lineChart.getAxisLeft();
//获取左 Y 轴格式化显示内容
yLeftAxis.setValueFormatter(new TempValueFormatter());
yLeftAxis.setAxisMinimum(23f);//设置最小值
yLeftAxis.setGranularity(2f);//设置Y轴刻度间距
yLeftAxis.setLabelCount(list.size(), false); // 强制设置标签个数
//获取右边的Y轴
YAxis yRightAxis=lineChart.getAxisRight();
yRightAxis.setEnabled(true);
yRightAxis.setValueFormatter(new TempValueFormatter());
yRightAxis.setAxisMinimum(23f);//设置最小值
yRightAxis.setGranularity(2f);//设置Y轴刻度间距
yRightAxis.setLabelCount(list.size(), false); // 强制设置标签个数
}
}
【实验名称】 实验6.2 升级最近气温变化曲线图界面(选做)
【实验目的】
- 掌握 LitePal 框架的应用
- 掌握 MPAndroidChart 框架
【实验环境】
- 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
- 计算机可以访问互联网。
- 内存:至少6G
- 硬盘:至少空余20G
- JDK 8或以上
- Android Studio
【实验要求】
- (1)本实验承接[实验6.1](#【实验名称】 实验6.1 开发最近气温变化曲线图界面)项目
- (2)修改实验6.1 的
ThermometerActivity
,实现数据从 Sqlite 读取时间和温度数据。
【参考代码】
TempVo
是使用 Litepal 框架实现的保存时间和温度信息的类。
package iot.app.smarthome.model.device;
import org.litepal.annotation.Column;
import org.litepal.crud.LitePalSupport;
public class TempVo extends LitePalSupport {
@Column(unique = true)
private int dateHour;//默认格式yyyyMMddhh
private float degree;
public int getDateHour() {
return dateHour;
}
public float genDateHourF() {
return dateHour%100;
}
public void setDateHour(int dateHour) {
this.dateHour = dateHour;
}
public float getDegree() {
return degree;
}
public void setDegree(float degree) {
this.degree = degree;
}
}
litepal.xml
配置
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="SmartHome" />
<version value="3" />
<list>
<mapping class="iot.app.smarthome.model.device.Device" />
<mapping class="iot.app.smarthome.model.user.UserInfoVo" />
<mapping class="iot.app.smarthome.model.device.TempVo" />
</list>
</litepal>
【实验名称】 实验6.3 实现多种图组合界面(选做)
【实验目的】
- 掌握 CombinedChart 和 CombinedData 的使用
- 掌握 MPAndroidChart 框架
【实验环境】
- 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
- 计算机可以访问互联网。
- 内存:至少6G
- 硬盘:至少空余20G
- JDK 8或以上
- Android Studio
【实验要求】
- (1)实现
TempHumStatisticActivity
,实现柱状图和曲线图组合展示的界面。
【参考代码】
- TempHumStatisticActivity,请完善其中的代码。
package iot.app.smarthome.ui.device;
import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.github.mikephil.charting.charts.CombinedChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.CombinedData;
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.IndexAxisValueFormatter;
import com.github.mikephil.charting.formatter.ValueFormatter;
import java.util.ArrayList;
import java.util.List;
import iot.app.smarthome.R;
public class TempHumStatisticActivity extends AppCompatActivity {
private CombinedChart dataChart;//图表
private CombinedData data;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_energy_statistic);
dataChart = (CombinedChart) findViewById(R.id.combinedChart);
showDataOnChart();
Legend legend = dataChart.getLegend();
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
}
/**
* 展示数据
*/
private void showDataOnChart() {
//绘制图表数据
data = new CombinedData();
//TODO:设置折线图数据
//TODO:设置柱状图数据
//TODO:设置横坐标数据
//TODO:设置右侧纵坐标数据
//TODO:设置左侧纵坐标数据
dataChart.setTouchEnabled(false);
dataChart.getDescription().setEnabled(false);
dataChart.setDrawGridBackground(false);
dataChart.setDrawBarShadow(false);
dataChart.setHighlightFullBarEnabled(true);
dataChart.animateX(2000);
}
/**
* 设置横坐标数据
*/
private void setAxisXBottom() {
List<String> valuesX = new ArrayList<>();
String date[] = {"1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"};
for (int i = 0;i < date.length;i++){
valuesX.add(date[i]);
}
XAxis bottomAxis = dataChart.getXAxis();
bottomAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
bottomAxis.setCenterAxisLabels(true);
bottomAxis.setValueFormatter(new IndexAxisValueFormatter(valuesX));
bottomAxis.setAxisMinimum(data.getXMin());
bottomAxis.setAxisMaximum(data.getXMax() + 0.5f);
bottomAxis.setLabelCount(date.length);
bottomAxis.setAvoidFirstLastClipping(false);
}
/**
* 设置右侧纵坐标数据
*/
private void setAxisYRight() {
YAxis right = dataChart.getAxisRight();
right.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return value + "℃";
}
});
right.setDrawGridLines(false);
}
/**
* 设置左侧纵坐标数据
*/
private void setAxisYLeft() {
YAxis left = dataChart.getAxisLeft();
left.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return value + "ml";
}
});
left.setDrawGridLines(false);
}
/**
* 设置折线图绘制数据
* 温度
* @return
*/
public LineData getLineData() {
LineData lineData = new LineData();
List<Entry> customCounts = new ArrayList<>();
float[] data = {2.0f, 2.2f, 3.3f, 4.5f, 6.3f, 10.2f, 20.3f, 23.4f, 23.0f, 16.5f, 12.0f, 6.2f};
//人数
for (int i = 0; i < data.length; i++) {
customCounts.add(new Entry(i + 0.5f,data[i]));
}
LineDataSet lineDataSet = new LineDataSet(customCounts,"平均温度");
lineDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
lineDataSet.setColor(Color.parseColor("#66A3AB"));
lineDataSet.setCircleColor(Color.parseColor("#66A3AB"));
lineDataSet.setCircleRadius(5);
lineDataSet.setLineWidth(3);
lineDataSet.setValueTextSize(12);
lineDataSet.setValueTextColor(Color.parseColor("#66A3AB"));
lineData.addDataSet(lineDataSet);
return lineData;
}
/**
* 设置柱状图绘制数据
*
* @return
*/
public BarData getBarData() {
BarData barData = new BarData();
//蒸发量
List<BarEntry> amounts = new ArrayList<>();
float z[] = {2.0f, 4.9f, 7.0f, 23.2f, 25.6f, 76.7f, 135.6f, 162.2f, 32.6f, 20.0f, 6.4f, 3.3f};
//降水量
List<BarEntry> averages = new ArrayList<>();
float j[] = {2.6f, 5.9f, 9.0f, 26.4f, 28.7f, 70.7f, 175.6f, 182.2f, 48.7f, 18.8f, 6.0f, 2.3f};
//添加数据
for (int i = 0; i < z.length; i++) {
amounts.add(new BarEntry(i,z[i]));
averages.add(new BarEntry(i,j[i]));
}
//设置总数的柱状图
BarDataSet amountBar = new BarDataSet(amounts,"蒸发量");
amountBar.setAxisDependency(YAxis.AxisDependency.LEFT);
amountBar.setColor(Color.parseColor("#C23531"));
//设置平均的柱状图
BarDataSet averageBar = new BarDataSet(averages,"降水量");
averageBar.setAxisDependency(YAxis.AxisDependency.LEFT);
averageBar.setColor(Color.parseColor("#2F4554"));
amountBar.setValueTextSize(10);
averageBar.setValueTextSize(10);
barData.addDataSet(amountBar);
barData.addDataSet(averageBar);
//设置柱状图显示的大小
float groupSpace = 0.06f;
float barSpace = 0.02f;
float barWidth = 0.45f;
barData.setBarWidth(barWidth);
barData.groupBars(0, groupSpace, barSpace);
return barData;
}
}