Skip to content

Instantly share code, notes, and snippets.

@achuinard
Created July 21, 2015 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save achuinard/1dd034203e9a4e742a87 to your computer and use it in GitHub Desktop.
Save achuinard/1dd034203e9a4e742a87 to your computer and use it in GitHub Desktop.
public abstract class CustomSortFirebaseRecyclerAdapter<T> extends RecyclerView.Adapter implements ChildEventListener {
protected Query mRef;
private Class<T> mModelClass;
private RecyclerQuestionAnswerer<T> mRecyclerQuestionAnswerer;
protected SortedList<T> mModels;
protected Map<String, T> mModelKeys;
private ChildEventListener mListener;
protected Context mContext;
public CustomSortFirebaseRecyclerAdapter(Query ref, Class<T> modelClass, final RecyclerQuestionAnswerer<T> recyclerQuestionAnswerer) {
mRef = ref;
mModelClass = modelClass;
mModelKeys = Collections.synchronizedMap(new HashMap<String, T>());
mModels = new SortedList<T>(modelClass, new SortedListAdapterCallback<T>(this) {
@Override
public int compare(T lhs, T rhs) {
return recyclerQuestionAnswerer.compare(lhs, rhs);
}
@Override
public boolean areContentsTheSame(T oldItem, T newItem) {
return recyclerQuestionAnswerer.areContentsTheSame(oldItem, newItem);
}
@Override
public boolean areItemsTheSame(T item1, T item2) {
return recyclerQuestionAnswerer.areItemsTheSame(item1, item2);
}
});
mRecyclerQuestionAnswerer = recyclerQuestionAnswerer;
mListener = mRef.addChildEventListener(this);
}
public void cleanup() {
mRef.removeEventListener(mListener);
}
@Override
public long getItemId(int i) {
return mModels.get(i).hashCode();
}
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
T model = dataSnapshot.getValue(CustomSortFirebaseRecyclerAdapter.this.mModelClass);
if (mRecyclerQuestionAnswerer.include(model)) {
final String key = dataSnapshot.getKey();
mModelKeys.put(key, model);
mModels.add(model);
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
final T value = dataSnapshot.getValue(mModelClass);
final String key = dataSnapshot.getKey();
if (mRecyclerQuestionAnswerer.include(value) && !mModelKeys.containsKey(key)) {
onChildAdded(dataSnapshot, previousChildName);
} else if (!mRecyclerQuestionAnswerer.include(value) && mModelKeys.containsKey(key)) {
onChildRemoved(dataSnapshot);
} else if (mRecyclerQuestionAnswerer.include(value) && mModelKeys.containsKey(key)){
final T oldValue = mModelKeys.get(key);
mModelKeys.put(key, value);
mModels.updateItemAt(mModels.indexOf(oldValue), value);
}
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
final String key = dataSnapshot.getKey();
final T oldModel = mModelKeys.get(key);
mModelKeys.remove(key);
mModels.remove(oldModel);
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
// nop
}
@Override
public void onCancelled(FirebaseError firebaseError) {
Log.e(getClass().getName(), "Listen was cancelled, no more updates will occur");
}
@Override
public int getItemCount() {
return mModels.size();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return onCreateViewHolderImpl(parent, viewType);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
onBindViewHolderImpl(holder, position);
}
protected abstract int getEmptyTextId();
protected abstract RecyclerView.ViewHolder onCreateViewHolderImpl(ViewGroup parent, int viewType);
protected abstract void onBindViewHolderImpl(RecyclerView.ViewHolder vh, int position);
}
public interface RecyclerQuestionAnswerer<T> {
boolean include(T model);
int compare(T lhs, T rhs);
boolean areContentsTheSame(T lhs, T rhs);
boolean areItemsTheSame(T lhs, T rhs);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment