解决这个问题并仍然使用 FirebaseUI 中的 FirebaseRecyclerAdapter 的一种方法是像这样扩展 FirebaseArray:
import com.firebase.ui.database.FirebaseArray;
import com.firebase.ui.database.SnapshotParser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.Query;
import java.util.HashSet;
import java.util.Set;
public class FilterableFirebaseArray extends FirebaseArray {
private Set<String> excludes = new HashSet<>();
public FilterableFirebaseArray(Query query, Class aClass) {
super(query, aClass);
}
public FilterableFirebaseArray(Query query, SnapshotParser parser) {
super(query, parser);
}
public void addExclude(String key) {
excludes.add(key);
}
public void removeExclude(String key) {
excludes.remove(key);
}
@Override
public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildAdded(snapshot, excludes.contains(previousChildKey)? null : previousChildKey);
}
}
@Override
public void onChildChanged(DataSnapshot snapshot, String previousChildKey) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildChanged(snapshot, excludes.contains(previousChildKey)? null : previousChildKey);
}
}
@Override
public void onChildMoved(DataSnapshot snapshot, String previousChildKey) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildMoved(snapshot, excludes.contains(previousChildKey)? null : previousChildKey);
}
}
@Override
public void onChildRemoved(DataSnapshot snapshot) {
if (!excludes.contains(snapshot.getKey())) {
super.onChildRemoved(snapshot);
}
}
}
...然后像这样使用它:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView userListView = (RecyclerView) findViewById(R.id.userList);
userListView.setLayoutManager(new LinearLayoutManager(this));
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query query = ref.orderByValue();
ClassSnapshotParser parser = new ClassSnapshotParser<UserProfile>(UserProfile.class);
FilterableFirebaseArray filterableFirebaseArray = new FilterableFirebaseArray(query, parser);
filterableFirebaseArray.addExclude(FirebaseAuth.getInstance().getCurrentUser().getUid());
FirebaseRecyclerAdapter mAdapter = new FirebaseRecyclerAdapter<UserProfile, UserListEntryHolder>(
filterableFirebaseArray,
R.layout.userlist_entry,
UserListEntryHolder.class) {
@Override
protected void populateViewHolder(UserListEntryHolder viewHolder, UserProfile model, int position) {
viewHolder.bind(model);
}
};
userListView.setAdapter(mAdapter);
}
“魔法”发生在被覆盖的 onChildAdded 方法中,我们忽略了由指定键标识的子项。在此示例中,我只是将当前用户的 UID 添加到排除列表中。因为这符合我的数据库设计。
您可以轻松扩展功能以忽略具有特定属性的子项。
奖励:如果您更喜欢 Kotlin 方式(像我一样),您会这样做:
import com.firebase.ui.database.FirebaseArray
import com.firebase.ui.database.SnapshotParser
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.Query
class FilterableFirebaseArray<T> : FirebaseArray<T> {
val excludedKeys = HashSet<String?>()
constructor(query: Query, tClass: Class<T>) : super(query, tClass)
constructor(query: Query, parser: SnapshotParser<T>) : super(query, parser)
override fun onChildAdded(snapshot: DataSnapshot, previousChildKey: String?) {
if (!excludedKeys.contains(snapshot.key))
super.onChildAdded(snapshot, if (excludedKeys.contains(previousChildKey)) null else previousChildKey)
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildKey: String?) {
if (!excludedKeys.contains(snapshot.key))
super.onChildChanged(snapshot, previousChildKey)
}
override fun onChildMoved(snapshot: DataSnapshot, previousChildKey: String?) {
if (!excludedKeys.contains(snapshot.key))
super.onChildMoved(snapshot, previousChildKey)
}
override fun onChildRemoved(snapshot: DataSnapshot) {
if (!excludedKeys.contains(snapshot.key))
super.onChildRemoved(snapshot)
}
}
...然后像这样使用它:
override fun onStart() {
super.onStart()
if (currentUser != null) {
userList.adapter = getAdapter()
}
}
private fun getAdapter(): FirebaseRecyclerAdapter<UserProfile, UserListEntryHolder> {
val query = userProfilesReference.orderByValue()
val parser = ClassSnapshotParser<UserProfile>(UserProfile::class.java)
val filterableFirebaseArray = FilterableFirebaseArray<UserProfile>(query, parser)
filterableFirebaseArray.excludes.add(currentUser?.uid)
return object : FirebaseRecyclerAdapter<UserProfile, UserListEntryHolder>(
filterableFirebaseArray,
R.layout.userlist_entry,
UserListEntryHolder::class.java) {
public override fun populateViewHolder(entryHolder: UserListEntryHolder, userProfile: UserProfile, position: Int) {
entryHolder.bind(userProfile)
}
}
}
更新代码以解决与 onChildChanged、onChildMoved 等相关的 IllegalArgumentExceptions。