问题
I have a very simple Firebase Database which looks like this:
This is my model:
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;}
}
All i want to do, is to display in a ListView
only the lists that belong to a single user and have the value of true
. With this code:
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);
I get an empty view as shown in the image below.
How can i display the items in the ListView
correctly?
回答1:
You didn't specify it on the Question, but I'm assuming your app is a Shopping List where a single list can be used by many users.
I suggest you restructure your database to simplify queries: Add one more node where you store each user's list name and id. Like this:
"userLists" : {
"gmail@gmail" : {
"-Kbvasnd23sdj" : "bbb",
"-Kbvasndaisdj" : "aaa",
"-Kbvasxzvisdj" : "ddd"
},
"ymail@ymail" : {
"-Kbvasndaisxz" : "ccc"
}
}
This way, when you want to get all the lists from a specific user, you'd use:
Query query = FirebaseDatabase.getInstance().getReference().child("userLists/gmail@gmail");
And you'd obviously want to give the user the ability to click on an item and see the list. You can do that by making sure that the push id in each node from userLists
is the same as the id from the ShoppingLists
node.
In short: When you're displaying the list, you read the data from the userLists node. When you're displaying the list details, you read data from the ShoppingLists node. Something that you must keep in mind when creating databases on Firebase is:
Structure your data after your view.
For more details on how to do his, I recommend you watch the Firebase Database for SQL Developers series.
回答2:
You're not showing what query
is in your code, so I'm assuming that it's just a DatabaseReference for everything at /ShoppingLists
. If you're doing that, you're going to get a call for populateView for every child at that location. This means you're going to be asked to make a view for every child. You don't get to choose whether or not a view will appear for that item.
It looks like you're assuming that your if
statement in populateView will skip over that item. But what's actually happening is that you're simply allowing an empty view to occupy that spot in the list.
Instead, you should come up with a query that generates only the items of interest to your list. This means you'll have to tell Firebase to filter for children that meet your criteria. Unfortunately, your criteria as two conditions (number of users under usersMap and the value of the boolean for that user's key). Firebase can't perform filtering like that.
So, FirebaseListAdapter won't help you with this, because it only takes input from a single Query that you specify.
Instead, you'll have to read the entire contents of the location, manually filter out the items you don't want, and build a list of items you do want. You can build an Adapter with that list, and it can then become the input to a ListView (or better, a RecyclerView).
来源:https://stackoverflow.com/questions/42029339/how-to-display-the-exact-number-of-items-from-a-firebase-database-in-a-listview