All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.firebase.ui.database.FirebaseRecyclerAdapter Maven / Gradle / Ivy

There is a newer version: 8.0.2
Show newest version
package com.firebase.ui.database;

import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.Query;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * This class is a generic way of backing a {@link RecyclerView} with a Firebase location. It
 * handles all of the child events at the given Firebase location and marshals received data into
 * the given class type.
 * 

* See the README * for an in-depth tutorial on how to set up the FirebaseRecyclerAdapter. * * @param The Java class that maps to the type of objects stored in the Firebase location. * @param The {@link RecyclerView.ViewHolder} class that contains the Views in the layout that * is shown for each object. */ public abstract class FirebaseRecyclerAdapter extends RecyclerView.Adapter implements FirebaseAdapter { private static final String TAG = "FirebaseRecyclerAdapter"; protected final ObservableSnapshotArray mSnapshots; protected final Class mViewHolderClass; protected final int mModelLayout; /** * @param snapshots The data used to populate the adapter * @param modelLayout This is the layout used to represent a single item in the list. You * will be responsible for populating an instance of the corresponding * view with the data from an instance of modelClass. * @param viewHolderClass The class that hold references to all sub-views in an instance * modelLayout. */ public FirebaseRecyclerAdapter(ObservableSnapshotArray snapshots, @LayoutRes int modelLayout, Class viewHolderClass) { mSnapshots = snapshots; mViewHolderClass = viewHolderClass; mModelLayout = modelLayout; startListening(); } /** * @param parser a custom {@link SnapshotParser} to convert a {@link DataSnapshot} to the model * class * @param query The Firebase location to watch for data changes. Can also be a slice of a * location, using some combination of {@code limit()}, {@code startAt()}, and * {@code endAt()}. Note, this can also be a {@link DatabaseReference}. * @see #FirebaseRecyclerAdapter(ObservableSnapshotArray, int, Class) */ public FirebaseRecyclerAdapter(SnapshotParser parser, @LayoutRes int modelLayout, Class viewHolderClass, Query query) { this(new FirebaseArray<>(query, parser), modelLayout, viewHolderClass); } /** * @see #FirebaseRecyclerAdapter(SnapshotParser, int, Class, Query) */ public FirebaseRecyclerAdapter(Class modelClass, @LayoutRes int modelLayout, Class viewHolderClass, Query query) { this(new ClassSnapshotParser<>(modelClass), modelLayout, viewHolderClass, query); } @Override public void startListening() { if (!mSnapshots.isListening(this)) { mSnapshots.addChangeEventListener(this); } } @Override public void cleanup() { mSnapshots.removeChangeEventListener(this); } @Override public void onChildChanged(ChangeEventListener.EventType type, DataSnapshot snapshot, int index, int oldIndex) { switch (type) { case ADDED: notifyItemInserted(index); break; case CHANGED: notifyItemChanged(index); break; case REMOVED: notifyItemRemoved(index); break; case MOVED: notifyItemMoved(oldIndex, index); break; default: throw new IllegalStateException("Incomplete case statement"); } } @Override public void onDataChanged() { } @Override public void onCancelled(DatabaseError error) { Log.w(TAG, error.toException()); } @Override public T getItem(int position) { return mSnapshots.getObject(position); } @Override public DatabaseReference getRef(int position) { return mSnapshots.get(position).getRef(); } @Override public int getItemCount() { return mSnapshots.size(); } @Override public VH onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false); try { Constructor constructor = mViewHolderClass.getConstructor(View.class); return constructor.newInstance(view); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } @Override public int getItemViewType(int position) { return mModelLayout; } @Override public void onBindViewHolder(VH viewHolder, int position) { T model = getItem(position); populateViewHolder(viewHolder, model, position); } /** * Each time the data at the given Firebase location changes, this method will be called for * each item that needs to be displayed. The first two arguments correspond to the mLayout and * mModelClass given to the constructor of this class. The third argument is the item's position * in the list. *

* Your implementation should populate the view using the data contained in the model. * * @param viewHolder The view to populate * @param model The object containing the data used to populate the view * @param position The position in the list of the view being populated */ protected abstract void populateViewHolder(VH viewHolder, T model, int position); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy