I am trying to implement a custom PagerAdapter implementing Firebase the same way that FirebaseListAdapter and FirebaseRecyclerAdapter do. I have looked at the source code on GitHub here but I am getting a couple errors in Android Studio. Here is my FirebasePagerAdapter utilizing a lot of classes from the given link:
public abstract class FirebasePagerAdapter<T> extends PagerAdapter implements FirebaseAdapter, ChangeEventListener {
private static String TAG = "firebasepageradapter";
protected final Activity mActivity;
protected final ObservableSnapshotArray<T> mSnapshots;
protected final int mLayout;
/**
* @param activity The {@link Activity} containing the {@link android.support.v4.view.ViewPager}
* @param modelLayout This is the layout used to represent a single list item. You will be
* responsible for populating an instance of the corresponding view with the
* data from an instance of modelClass.
* @param snapshots The data used to populate the adapter
*/
public FirebasePagerAdapter(Activity activity,
ObservableSnapshotArray<T> snapshots,
@LayoutRes int modelLayout) {
mActivity = activity;
mSnapshots = snapshots;
mLayout = 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()}. <b>Note, this can also be a {@link DatabaseReference}.</b>
* @see #FirebasePagerAdapter(Activity, ObservableSnapshotArray, int)
*/
public FirebasePagerAdapter(Activity activity,
SnapshotParser<T> parser,
@LayoutRes int modelLayout,
Query query) {
this(activity, new FirebaseArray<>(query, parser), modelLayout);
}
/**
* @see #FirebasePagerAdapter(Activity, SnapshotParser, int, Query)
*/
public FirebasePagerAdapter(Activity activity,
Class<T> modelClass,
@LayoutRes int modelLayout,
Query query) {
this(activity, new ClassSnapshotParser<>(modelClass), modelLayout, query);
}
@Override
public int getCount() {
return mSnapshots.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
@Override
public void startListening() {
if (!mSnapshots.isListening(this)) {
mSnapshots.addChangeEventListener(this);
}
}
@Override
public void cleanup() {
mSnapshots.removeChangeEventListener(this);
}
@Override
public Object getItem(int position) {
return mSnapshots.get(position).getKey().hashCode();
}
@Override
public DatabaseReference getRef(int position) {
return mSnapshots.get(position).getRef();
}
@Override
public void onChildChanged(ChangeEventListener.EventType type, DataSnapshot snapshot, int index, int oldIndex) {
notifyDataSetChanged();
}
@Override
public void onDataChanged() {
}
@Override
public void onCancelled(DatabaseError error) {
Log.w(TAG, error.toException());
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = mActivity.getLayoutInflater().inflate(mLayout, container, false);
T model = getItem(position);
// Call out to subclass to marshall this model into the provided view
populateView(view, model, position);
return view;
}
/**
* 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.
* <p>
* Your implementation should populate the view using the data contained in the model.
*
* @param v 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 populateView(View v, T model, int position);
}
Classes used from given link:
I have intensely searched Google and SO for an example or solution but despite the need for a FirebasePagerAdapter, no one has come up with a solution or at least made it public. I would like to get this working and make it public for other developers that may find it useful.
The errors I am getting are with T model = getItem(position);
in instantiateItem method "incompatible types: required T, found object" and with this(activity, new FirebaseArray<>(query, parser), modelLayout);
"cannot infer arguments".
My hope is that by resolving those errors, the adapter would work as expected.
I have solved the issue by changing the getItem method to a GenericType public T getItem(int position)
. It works perfectly now. Here is my complete FirebasePagerAdapter class:
public abstract class FirebasePagerAdapter<T> extends PagerAdapter implements FirebaseAdapter, ChangeEventListener {
private static String TAG = "firebasepageradapter";
protected final Activity mActivity;
protected final ObservableSnapshotArray<T> mSnapshots;
protected final int mLayout;
/**
* @param activity The {@link Activity} containing the {@link android.support.v4.view.ViewPager}
* @param modelLayout This is the layout used to represent a single list item. You will be
* responsible for populating an instance of the corresponding view with the
* data from an instance of modelClass.
* @param snapshots The data used to populate the adapter
*/
public FirebasePagerAdapter(Activity activity,
ObservableSnapshotArray<T> snapshots,
@LayoutRes int modelLayout) {
mActivity = activity;
mSnapshots = snapshots;
mLayout = 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()}. <b>Note, this can also be a {@link DatabaseReference}.</b>
* @see #FirebasePagerAdapter(Activity, ObservableSnapshotArray, int)
*/
public FirebasePagerAdapter(Activity activity,
SnapshotParser<T> parser,
@LayoutRes int modelLayout,
Query query) {
this(activity, new FirebaseArray<>(query, parser), modelLayout);
}
/**
* @see #FirebasePagerAdapter(Activity, SnapshotParser, int, Query)
*/
public FirebasePagerAdapter(Activity activity,
Class<T> modelClass,
@LayoutRes int modelLayout,
Query query) {
this(activity, new ClassSnapshotParser<>(modelClass), modelLayout, query);
}
@Override
public int getCount() {
return mSnapshots.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void startListening() {
if (!mSnapshots.isListening(this)) {
mSnapshots.addChangeEventListener(this);
}
}
@Override
public void cleanup() {
mSnapshots.removeChangeEventListener(this);
}
@Override
public T getItem(int position) {
return mSnapshots.getObject(position);
}
@Override
public DatabaseReference getRef(int position) {
return mSnapshots.get(position).getRef();
}
@Override
public void onChildChanged(ChangeEventListener.EventType type, DataSnapshot snapshot, int index, int oldIndex) {
notifyDataSetChanged();
}
@Override
public void onDataChanged() {
}
@Override
public void onCancelled(DatabaseError error) {
Log.w(TAG, error.toException());
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = mActivity.getLayoutInflater().inflate(mLayout, container, false);
//T model = getItem(position);
T model = getItem(position);
// Call out to subclass to marshall this model into the provided view
populateView(view, model, position);
container.addView(view);
return view;
}
/**
* 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.
* <p>
* Your implementation should populate the view using the data contained in the model.
*
* @param v 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 populateView(View v, T model, int position);
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((RelativeLayout)object);
}
}
I have posted everything needed for this to work on GitHub for anyone else that may find it useful. You can find it here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.