- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前,我正在构建一个使用 Firebase 数据库的 Android 应用程序。
在我的代码中,我试图获取我的 Firebase 数据库特定路径中的子项数量。定义了 Firebase 特定路径的引用后,我创建了一个监听器以获取 DataSnapshot,然后调用 getChildrenCount()。
之后,我想在 FOR 循环中使用这个结果。但是,代码不起作用。
它似乎首先执行了 FOR 循环(我意识到因为 Log.v("NUM_OF_PRODUCTS",numOfProducts+"")
输出 0 而不是 3)并且 Listener 在之后执行,而在代码中,监听器代码在前,然后是 FOR-Loop 代码。
我的部分代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_selection);
selected_cat = getIntent().getExtras().getString("pass_selected_cat");
listView = (ListView) findViewById(R.id.listView);
final ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(adapter);
fbdatabase = FirebaseDatabase.getInstance();
fbref_products = fbdatabase.getReference("PRODUCTS/SM_0/" + selected_cat);
//Listener for getting numOfProducts.
fbref_products.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
numOfProducts = (int) dataSnapshot.getChildrenCount();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
//Print numOfProducts before FOR-Loop being executed.
Log.v("NUM_OF_PRODUCTS",numOfProducts+"");
//FOR-Loop
for (int i = 0; i < numOfProducts; i++) {
String str = i + "";
DatabaseReference product_ref = fbref_products.child(str);
product_ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
String productName = (String) map.get("productName");
arrayList.add(productName);
adapter.notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError databaseError) {
//textView.setText("The read failed: " + databaseError.getMessage());
}
});
}
如果不是变量 numOfProducts
,我的代码工作正常,我们有一个特定的数字。
谁能帮帮我??
最佳答案
来自 Firebase 数据库的数据是异步加载的。当您运行 for
循环时,它还没有加载。
如果在代码中放置一些日志语句,最容易看到这一点:
System.out.println("Before attaching listener");
fbref_products.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("In onDataChange");
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
System.out.println("After attaching listener");
当你运行它时,输出将是:
Before attaching listener
After attaching listener
In onDataChange
这可能不是您期望的顺序。但这完美地解释了为什么当您开始循环时 numOfProducts
仍然是 0:数据只是还没有从 Firebase 加载。
几乎每个开发人员的最初 react 都是“我不想要这个。我如何让它以正确的顺序执行?”这是一种自然 react ,但在针对 Web/云 API 进行编程时,您必须抑制这种 react 才能到达任何地方。我还建议在这里阅读我的回答:Setting Singleton property value in Firebase Listener
解决方案是将您的解决方案从“首先我将获取产品数量,然后我将遍历产品”重新定义为“每当我获取产品时,我将遍历它们”。
在代码中是:
fbref_products.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
numOfProducts = (int) dataSnapshot.getChildrenCount();
for (int i = 0; i < numOfProducts; i++) {
String str = i + "";
DatabaseReference product_ref = fbref_products.child(str);
product_ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
String productName = (String) map.get("productName");
arrayList.add(productName);
adapter.notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError databaseError) {
//textView.setText("The read failed: " + databaseError.getMessage());
}
});
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
除了整个处理异步事件之外,您还可以显着简化这段代码:
fbref_products.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot productSnapshot: dataSnapshot.getChildren()) {
String productName = productSnapshot.child("productName").getValue(String.class);
arrayList.add(productName);
adapter.notifyDataSetChanged();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
变化:
您应该考虑的另一项更改是保留一个单独的产品名称列表。您现在检索所有产品数据以显示名称列表,这是一种浪费。如果您保留一个仅包含产品名称的单独列表,则可以改为加载它。在使用 Firebase(或几乎任何 NoSQL 数据库)时,您会发现一个共同的主题:按照您在屏幕上显示数据的方式对数据库中的数据进行建模。
关于Android - Firebase - getChildrenCount() 方法问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39941542/
在我的数据库中,假设有超过 5000 个用户,现在如果我在主父节点中使用 getChildrenCount() 来获取我有多少用户 我知道 getChildrenCount 会返回一个长整数,其中包含
目前,我正在构建一个使用 Firebase 数据库的 Android 应用程序。 在我的代码中,我试图获取我的 Firebase 数据库特定路径中的子项数量。定义了 Firebase 特定路径的引用后
我正在尝试计算已输入特定子级到 Firebase 数据库中的数据量。 public void onDataChange(DataSnapshot dataSnapshot) { if (!regist
我正在开发一个 NavigationDrawer与 ListView 。我有一个ArrayList到 ListView 的项目 部分代码: private ListView mDrawerList;
在我的应用程序中,我尝试获取所有可用的用户。为此,每个用户都有一个参数,要么是“真”,要么是“假”。我想返回该参数为“真”的用户数量。 在这种情况下,数据如下所示: 我试过这样做,代码被切到必要的部分
我正在使用 VisualTreeHelper.GetChildrenCount() 来查找子控件,但它总是返回 0。 这是我的代码
我正在使用 BaseExpandableListAdapter 并尝试创建一个动态列表,当您选中或取消选中其他元素时,其中的元素会出现和消失。该组是我创建的调用模式的对象的 ArrayList,而子项
这个异常让我抓狂。每当我的主要 Activity 的进程被杀死然后恢复时,由于我的 expandableListView 中的空指针异常,我的应用程序强制关闭。这是我的第一个 android 应用程序
在我的Activity 中,我更改了ExpandableListView 的基础数据HashMap,然后调用 ((BaseAdapter) myExpandableListView.getAdapte
我修改了已接受答案中的代码 here返回第一个找到的某种类型的控件。但是,当我尝试从窗口本身开始遍历时,VisualTreeHelper.GetChildrenCount 返回 0,尽管上面放置了一个
我想用不同的颜色为每个用户着色,所以我想从 firebase 检索用户 uuid 并向他们发送一些内容。我怎样才能像java中那样用for(int i....)来做到这一点? 这是我的 firebas
我将焦点移至打开的 Popup: wcl:FocusHelper.IsFocused="{Binding RelativeSource={RelativeSource Self}, Path=IsOp
我是一名优秀的程序员,十分优秀!