java - 读取 Firebase 上的数据并使用库 MpAndroidChart 绘制折线图
问题描述
大家好,我正在编写一个应用程序,它将读取存储在实时数据库中的数据,并使用Android Studio 的 Firebase
libaray 用这些数据绘制折线图。MPAndroidChart
我在实时数据库中的数据正在通过脚本不断获取并上传,该脚本将从串口Python
收集开发板上传感器的数据。(这部分可能与我的应用程序无关,因为数据结构已固定在) Waspmote
Firebase
实时数据库的结构如下图所示:
然后这是我MainActivity
的绘图应用程序代码:
public class MainActivity extends AppCompatActivity {
private LineChart Temp_linechart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
protected void onStart() {
super.onStart();
DatabaseReference mPostReference = FirebaseDatabase.getInstance().getReference("Indoor");
mPostReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Temp_linechart = (LineChart) findViewById(R.id.Data_of_Temp);
final ArrayList<Entry> yData = new ArrayList<>();
LineDataSet lineDataSet = new LineDataSet(yData,"Temp");
for (DataSnapshot ds : dataSnapshot.getChildren()){
Long tsLong = System.currentTimeMillis()/1000;
float SensorValue = (float)ds.child("P1").getValue();
yData.add(new Entry(tsLong,SensorValue));
}
LineData data = new LineData (lineDataSet);
Temp_linechart.setData(data);
Temp_linechart.notifyDataSetChanged();
Temp_linechart.invalidate();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, "Fail to load post", Toast.LENGTH_SHORT).show();
}
});
}
}
运行代码时没有错误,但是当我打开手机上创建的应用程序时,没有显示折线图,应用程序将在几秒钟后停止。显示:
sensordata_vis
已经停止
请帮忙,我真的是android studio的新手。谢谢。
好的,在我应用@Umar Hussain
's 方法之后。构建成功。在run
窗口中显示error1 error2
在logcat
窗口中显示error3 error4
谢谢
最后,我已经实现了我想要的,这是我编辑的代码:
public class MainActivity extends AppCompatActivity {
private LineChart Temp_linechart;
ArrayList<Entry> yData;
DatabaseReference mPostReference;
ValueEventListener valueEventListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Temp_linechart = (LineChart) findViewById(R.id.Data_of_Temp);
mPostReference = FirebaseDatabase.getInstance().getReference("Indoor");
mPostReference.addValueEventListener(valueEventListener= new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
yData = new ArrayList<>();
float i =0;
for (DataSnapshot ds : dataSnapshot.getChildren()){
i=i+1;
String SV = ds.child("P1").getValue().toString();
Float SensorValue = Float.parseFloat(SV);
yData.add(new Entry(i,SensorValue));
}
final LineDataSet lineDataSet = new LineDataSet(yData,"Temp");
LineData data = new LineData(lineDataSet);
Temp_linechart.setData(data);
Temp_linechart.notifyDataSetChanged();
Temp_linechart.invalidate();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
解决方案
首先将您的代码移动到侦听器之外的图表参考,到onCreate()
.
还将 MpAndroidChart 初始化移动到 oncreate 方法中。
final ArrayList<Entry> yData;
LineDataSet lineDataSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Temp_linechart = (LineChart) findViewById(R.id.Data_of_Temp);
yData = new ArrayList<>();
lineDataSet = new LineDataSet(yData,"Temp");
LineData data = new LineData (lineDataSet);
Temp_linechart.setData(data);
Temp_linechart.notifyDataSetChanged();
//Temp_linechart.invalidate();
}
接下来在您的值事件侦听器中,仅清除数组列表并重新填充它。并在图表上调用通知和无效。
DatabaseReference mPostReference;
ValueEventListener valueEventListener;
@Override
protected void onStart() {
super.onStart();
mPostReference = FirebaseDatabase.getInstance().getReference("Indoor");
mPostReference.addValueEventListener(valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
yData.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()){
Long tsLong = System.currentTimeMillis()/1000;
float SensorValue = (float)ds.child("P1").getValue();
yData.add(new Entry(tsLong,SensorValue));
}
Temp_linechart.notifyDataSetChanged();
Temp_linechart.invalidate();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, "Fail to load post", Toast.LENGTH_SHORT).show();
}
});
}
最后,在您的 onStop 中删除侦听器,因为侦听器未与片段或活动生命周期绑定,您必须手动执行此操作。
PS:尝试使用 Java 中的 Camelcase 作为 Java 开发人员最常用的样式,并且易于阅读。
推荐阅读
- google-sheets-api - 如何根据单元格变化告诉客户发票状态
- python - Python 无法加载 boost.python dll
- intel-mkl - 静态和动态集群 MKL 有什么区别?
- qt5 - 在 Qt 中,如何根据另一个模型的更改来更新模型的布局?
- reactjs - 访问状态时,WebStorm 自动完成功能不适用于 ReactJs
- c# - 允许 API json 上的反斜杠
- python - 在 gridsearchcv 中正确使用 CV
- google-sheets - 我做了一个计算器,想使用一个按钮将总和存储到另一个单元格以保存单元格
- javascript - 如何使用 contextAPI 在调度中使用等待?
- java - 如何打开默认数字助理设置?