This is a custom FirebaseListAdapter from Emanuelet from which I created a FirebaseRecyclerAdapter.
public abstract class FirebaseRecyclerAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH > implements Filterable { private static final String LOG_TAG = "FirebaseListAdapter"; private Query mRef; private Class<T> mModelClass; private int mLayout; private LayoutInflater mInflater; protected Class<VH> mViewHolderClass; private List<T> mModels; private List<T> mFilteredModels; private List<String> mKeys = new ArrayList<>(); private Map<String, T> mModelKeys; private Map<String, T> mFilteredKeys; private ChildEventListener mListener; private FirebaseRecyclerAdapter.ValueFilter valueFilter; public FirebaseRecyclerAdapter(Query mRef, Class<T> mModelClass, int mLayout, Activity activity, Class<VH> viewHolderClass) { this.mRef = mRef; this.mModelClass = mModelClass; this.mLayout = mLayout; this.mViewHolderClass = viewHolderClass; mInflater = activity.getLayoutInflater(); mModels = new ArrayList<>(); mModelKeys = new HashMap<>();
Extend PostsQueryAdapter with FirebaseRecyclerAdapter
public class FirebasePostsQueryAdapter extends FirebaseRecyclerAdapter<Feeds, PostViewHolder> { Activity mActivity; Query query; public FirebasePostsQueryAdapter(Query mRef, int mLayout, Activity activity, Class<PostViewHolder> viewHolderClass) { super(mRef, Feeds.class, mLayout, activity, viewHolderClass); this.query = mRef; this.mActivity = activity; } @Override protected void populateViewHolder(final PostViewHolder viewHolder, final Feeds model, final int position, final List<String> mKeys) { viewHolder.setPhoto(model.getThumb_url()); viewHolder.setTimestamp(DateUtils.getRelativeTimeSpanString( (long) model.getTimestamp()).toString()); viewHolder.setAuthor(model.getUser().getFull_name(), model.getUser().getUid()); viewHolder.setIcon(model.getUser().getProfile_picture(), model.getUser().getUid()); viewHolder.setText(model.getText()); viewHolder.mPhotoView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(mActivity, SingleVideoView.class); intent.putExtra(Constants.INTENT_VIDEO,model.getVideo_url()); intent.putExtra(Constants.KEY, mKeys.get(position)); mActivity.startActivity(intent); } }); ValueEventListener likeListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { viewHolder.setNumLikes(dataSnapshot.getChildrenCount()); if (dataSnapshot.hasChild(FirebaseUtil.getCurrentUserId())) { viewHolder.setLikeStatus(PostViewHolder.LikeStatus.LIKED, mActivity); } else { viewHolder.setLikeStatus(PostViewHolder.LikeStatus.NOT_LIKED, mActivity); } } @Override public void onCancelled(DatabaseError databaseError) { } }; FirebaseUtil.getLikesRef().child(mKeys.get(position)).addValueEventListener(likeListener); viewHolder.mLikeListener = likeListener; } @Override protected List<Feeds> filters(List<Feeds> models, CharSequence constraint) { return null; } @Override protected Map<String, Feeds> filterKeys(List<Feeds> mModels) { return null; } }
Where do you fill in the data in FirebasePostsQueryAdapter
@Override public void onCreate() { super.onCreate(); mFirebaseRef = FirebaseDatabase.getInstance().getReference(POSTS_STRING); mFirebaseRef.keepSynced(true); this.geoFire = new GeoFire(FirebaseDatabase.getInstance().getReference(GEO_POINTS)); mItemListAdapter = new FirebasePostQueryAdapter(mFirebaseRef.equalTo(GEOFIRE_CHILD), getActivity(), R.layout.list_item_items); } @Override public void onConnected(Bundle bundle) { startLocationUpdates(); center = new GeoLocation(MainActivity.mLastLocation.getLatitude(), MainActivity.mLastLocation.getLongitude()); if (!mActiveGeoQuery) { center = new GeoLocation(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()); startGeoQuery(); mAdapter.notifyDataSetChanged(); } center = new GeoLocation(MainActivity.mLastLocation.getLatitude(), MainActivity.mLastLocation.getLongitude()); if (center.latitude != 0 && center.longitude != 0 && !mActiveGeoQuery) { startGeoQuery(); } else if (mActiveGeoQuery) { Log.d(TAG, "geoquery already active"); } else { Log.d(TAG, "center not setted"); //I first try to set the center at the Last Known Location if retrieved if (Double.isNaN(mCurrentLocation.getLatitude()) && mCurrentLocation.getLatitude() != 0) { center = new GeoLocation(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()); startGeoQuery(); } } fragment.checkForItems(); } private void startGeoQuery() { query = geoFire.queryAtLocation(center, 2); Log.d(TAG, "center: " + center.toString() + ", radius: " + 2); query.addGeoQueryEventListener(new GeoQueryEventListener() { @Override public void onKeyEntered(String key, GeoLocation location) { Log.d(TAG, "Key " + key + " entered the search area at [" + location.latitude + "," + location.longitude + "]"); DatabaseReference tempRef = mFirebaseRef.child(key); tempRef.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { // I add the deal only if it doesn't exist already in the adapter String key = snapshot.getKey(); if (!mAdapter.exists(key)) { Log.d(TAG, "item added " + key); mAdapter.addSingle(snapshot); mAdapter.notifyDataSetChanged(); } else { //...otherwise I will update the record Log.d(TAG, "item updated: " + key); mAdapter.update(snapshot, key); mAdapter.notifyDataSetChanged(); } } @Override public void onCancelled(DatabaseError databaseError) { } }); } @Override public void onKeyExited(String key) { Log.d(TAG, "deal " + key + " is no longer in the search area"); mAdapter.remove(key); fragment.isListEmpty(); } @Override public void onKeyMoved(String key, GeoLocation location) { Log.d(TAG, String.format("Key " + key + " moved within the search area to [%f,%f]", location.latitude, location.longitude)); DatabaseReference tempRef = mFirebaseRef.child(key); tempRef.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { // I add the deal only if it doesn't exist already in the adapter String key = snapshot.getKey(); if (!mAdapter.exists(key)) { Log.d(TAG, "item added " + key); mAdapter.addSingle(snapshot); mAdapter.notifyDataSetChanged(); } else { //...otherwise I will update the record Log.d(TAG, "item updated: " + key); mAdapter.update(snapshot, key); mAdapter.notifyDataSetChanged(); } } @Override public void onCancelled(DatabaseError databaseError) { } }); } @Override public void onGeoQueryReady() { Log.d(TAG, "All initial data has been loaded and events have been fired!"); fragment.isListEmpty(); mActiveGeoQuery = true; } @Override public void onGeoQueryError(DatabaseError error) { Log.e(TAG, "There was an error with this query: " + error); mActiveGeoQuery = false; } }); fragment.bindRecyclerView(); }