从嵌套的onDataChange修改列表 [英] Modifying a list from nested onDataChange
问题描述
我试图将数据(字符串名称)添加到嵌套onDataChange的列表中. 在外部onDataChange中,数据被添加到timeIntervals数组列表中.在嵌套的onDataChange中,我确实获得了字符串名称值,但是,它没有插入到timeIntervals数组列表中,因此没有显示在列表中.我不知道为什么会这样.对不起,错误的代码.截止日期临近.
I am trying to add data (The String name) to the list in the nested onDataChange. In the outer onDataChange, the data is being added to the timeIntervals arraylist. In the nested onDataChange, I do get the String name value, however, it is not being inserted into the the timeIntervals arraylist and thus does not show up in the List. I am not sure why this happens. Sorry about the bad code. the deadline is approaching.
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(current_id).child("week").child(day);
mUserDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
daySchedule = (ArrayList<Long>)dataSnapshot.getValue();
Log.d("daySchedule", "onDataChange: "+daySchedule.toString());
int k = 0;
startIndexes = new ArrayList<Integer>();
endIndexes = new ArrayList<Integer>();
timeIntervals = new ArrayList<String>();
apptindex = new ArrayList<Integer>();
apptnumber = new ArrayList<Long>();
for (int i = 0; i < daySchedule.size(); i++) {
//starthour = daySchedule.get(i);
if (daySchedule.get(i) == 1L) {
//Log.d("checkone", "onDataChange: ");
startIndexes.add(i);
k = i;
while (k <= 15 && daySchedule.get(k) == 1L) {
k = k + 1;
}
endIndexes.add(k-1);
i = k;
} else if (daySchedule.get(i) != 0) {
//Toast.makeText(DayAppointmentsActivity.this, "hi", Toast.LENGTH_SHORT).show();
apptindex.add(i);
apptnumber.add(daySchedule.get(i));
}
}
Log.d("startindexes", "onDataChange: "+startIndexes.toString());
Log.d("endindexes", "onDataChange: "+endIndexes.toString());
int starthour = 0;
int startmin = 0;
int endhour = 0;
int endmin = 0;
for (int j = 0; j < startIndexes.size(); j++) {
starthour = startIndexes.get(j);
int check1 = starthour;
if (starthour == 0) {
starthour = starthour + 9;
} else if (starthour % 2 == 0) {
starthour = 9 + (starthour / 2);
} else {
starthour = 9 + (starthour / 2);
startmin = 30;
}
endhour = endIndexes.get(j);
int check2 = endhour;
if (endhour == 0) {
endhour = endhour + 9;
} else if (endhour % 2 == 0) {
endhour = 9 + (endhour / 2);
} else {
endhour = 9 + (endhour / 2);
endmin = 30;
}
if (check1 == check2) {
if (check1 == 0) {
endmin = 30;
} else if (check2 % 2 == 0) {
endmin = 30;
} else {
endmin = 0;
endhour = endhour + 1;
}
}
Log.d("startingtime", "onDataChange: "+starthour + " " +startmin);
Log.d("endingtime", "onDataChange: "+endhour + " " +endmin);
String time = "Free: " + starthour + ":" + startmin + " to " + endhour + ":" + endmin;
timeIntervals.add(time);
//Toast.makeText(DayAppointmentsActivity.this, time, Toast.LENGTH_SHORT).show();
startmin = 0;
endmin = 0;
}
for (int j = 0; j < apptindex.size(); j++) {
int index = apptindex.get(j);
long apptnum = apptnumber.get(j);
String appnumString = Long.toString(apptnum);
if (daySchedule != null) {
mApptDatabase = FirebaseDatabase.getInstance().getReference().child("Appointments").child(appnumString);
mApptDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("targetName").getValue().toString();
Toast.makeText(DayAppointmentsActivity.this, name, Toast.LENGTH_SHORT).show();
timeIntervals.add(name);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
Log.d("timeintervals", "onDataChange: "+timeIntervals.toString());
listAdapter = new ArrayAdapter<String>(DayAppointmentsActivity.this,android.R.layout.simple_list_item_1,timeIntervals);
listView.setAdapter(listAdapter);
}
推荐答案
欢迎使用异步数据加载,它总是向您发送消息.与您的想法相反,数据被添加到了timeIntervals
.它只是在 打印后添加的.
Welcome to asynchronous data loading, which always messages you up. Contrary to what you think, the data is getting added to timeIntervals
. It's just being added after you print it.
最简单的方法是添加一些放置良好的日志语句:
The easiest way to see this is by adding some well placed log statements:
Log.d("timeintervals", "Before starting load additional data");
for (int j = 0; j < apptindex.size(); j++) {
int index = apptindex.get(j);
long apptnum = apptnumber.get(j);
String appnumString = Long.toString(apptnum);
if (daySchedule != null) {
mApptDatabase = FirebaseDatabase.getInstance().getReference().child("Appointments").child(appnumString);
mApptDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("timeintervals": "Additional data loaded");
String name = dataSnapshot.child("targetName").getValue().toString();
timeIntervals.add(name);
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
}
}
Log.d("timeintervals", "After starting load additional data");
运行此代码时,输出为:
When you run this code the output is:
开始加载其他数据之前
Before starting load additional data
开始加载其他数据后
已加载其他数据
已加载其他数据
...
这可能不是您期望的顺序.但这很好地解释了为什么timeIntervals
在打印时为什么不显示其他信息:尚未加载数据.
This is probably not the order you expected. But it explains perfectly why timeIntervals
doesn't show the additional information when you print it: the data hasn't been loaded yet.
这是因为Firebase异步从数据库加载数据,并且在加载数据时不会阻止您的应用程序.
This is because Firebase loads data from the database asynchronously and doesn't block your app while it's loading the data.
处理异步数据的典型解决方案是将需要数据的代码移到数据加载后触发的onDataChange
中.例如.如果将timeIntervals
的日志记录移到onDataChange
,它将在每次加载名称之一时记录间隔.
The typical solution for dealing with asynchronous data is to move the code that needs the data into the onDataChange
that fires when the data has loaded. E.g. if you move the logging of the timeIntervals
into onDataChange
it will log the intervals each time it loads one of the names.
要了解更多有关此的信息,我建议阅读以下内容:
To learn a lot more about this, I recommend reading these:
- 道格出色的博客文章
- 在Firebase Listener中设置Singleton属性值
- 从Firebase获取数据后,ArrayList显示为空数据库
- Firebase/Android:添加检索到的值从Firebase到arraylist返回空指针异常
- a的值在ValueEventListener中初始化全局变量后,将对其进行重置
- Android-从Firebase数据库中的片段加载数据
- Doug's excellent blog post
- Setting Singleton property value in Firebase Listener
- ArrayList is showing empty after getting data from firebase database
- Firebase/Android: Adding retrieved values from Firebase to arraylist returns null pointer exception
- Value of a global variable is reset after it is initialised in ValueEventListener
- Android - Load data from Firebase Database in Fragment
这篇关于从嵌套的onDataChange修改列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!