如何使用带有Android的FirebaseListAdapter在ListView中显示Firebase数据库中的确切项目数?

时间:2017-02-03 17:01:21

标签: android listview firebase firebase-realtime-database listadapter

我有一个非常简单的Firebase数据库,如下所示: enter image description here

这是我的模特:

public class ShoppingListModel {
    private String shoppingListName;
    private Map<String, String> usersMap;

    public ShoppingListModel() {}

    public void setShoppingListName(String shoppingListName) {this.shoppingListName = shoppingListName;}
    public String getShoppingListName() {return shoppingListName;}

    public void setUsersMap(Map<String, String> usersMap) {this.usersMap = usersMap;}
    public Map<String, String> getUsersMap() {return usersMap;}
}

我想要做的只是在ListView中仅显示属于单个用户且值为true的列表。使用此代码:

Query query = databaseReference.child("ShoppingLists").orderByChild("shoppingListName");
firebaseListAdapter = new FirebaseListAdapter<ShoppingListModel>(this, ShoppingListModel.class, android.R.layout.simple_list_item_1, query) {
        @Override
        protected void populateView(View v, ShoppingListModel slm, int position) {
            for (Map.Entry<String, String> entry : slm.getUsersMap().entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (key.equals("gmail@gmail,com") && value.equals("true")) {
                    ((TextView)v.findViewById(android.R.id.text1)).setText(slm.getShoppingListName());
                }
            }
        }
    };
    ListView listView = (ListView) findViewById(R.id.list_view);
    listView.setAdapter(firebaseListAdapter);

我得到一个空视图,如下图所示。

enter image description here

如何正确显示ListView中的项目?

2 个答案:

答案 0 :(得分:3)

您没有在代码中显示query,因此我假设它只是/ShoppingLists所有内容的DatabaseReference。如果您正在这样做,那么您将要为该位置的每个孩子拨打populateView。这意味着您将被要求为每个孩子制作一个视图。您无法选择是否为该项目显示视图。

看起来您假设populateView中的if语句将跳过该项。但实际发生的是你只是允许空视图占据列表中的那个位置。

相反,您应该提出一个查询,该查询仅生成列表中感兴趣的项目。这意味着您必须告知Firebase符合您的条件filter for children。不幸的是,您的条件是两个条件(usersMap下的用户数和该用户键的布尔值)。 Firebase无法执行此类过滤。

因此,FirebaseListAdapter不会帮助您,因为它只接受您指定的单个查询的输入。

相反,您必须阅读该位置的全部内容,手动过滤掉您不想要的项目,并构建您想要的项目列表。您可以使用该列表构建适配器,然后它可以成为ListView(或更好的,RecyclerView)的输入。

答案 1 :(得分:2)

您没有在问题中指定它,但我假设您的应用是购物清单,其中许多用户可以使用单个列表。

我建议您重构数据库以简化查询:添加一个节点,您可以在其中存储每个用户的列表名称和ID。像这样:

"userLists" : {
    "gmail@gmail" : {
      "-Kbvasnd23sdj" : "bbb",
      "-Kbvasndaisdj" : "aaa",
      "-Kbvasxzvisdj" : "ddd"
    },
    "ymail@ymail" : {
      "-Kbvasndaisxz" : "ccc"
    }
  }

这样,当您想要获取特定用户的所有列表时,您可以使用:

Query query = FirebaseDatabase.getInstance().getReference().child("userLists/gmail@gmail");

您显然希望让用户能够点击某个项目并查看列表。您可以通过确保userLists中每个节点中的推送ID与ShoppingLists节点中的ID相同来实现此目的。

简而言之:当您显示列表时,您将从userLists节点读取数据。当您显示列表详细信息时,您将从ShoppingLists节点读取数据。 在Firebase上创建数据库时必须注意的事项是:

  

在您查看后构建数据。

有关如何操作的详细信息,建议您观看Firebase Database for SQL Developers series