I implemented my adapter using the library, but still I am not able to make headers stick.
Here is my adapter implementation:
public class StickyFeedAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements StickyHeaderAdapter<StickyFeedAdapter.HeaderViewHolder> {
protected final String TAG = getClass().getSimpleName();
private Context context;
private List<FeedItems> feedItems;
private Fragment fragment;
String API;
private String token;
TinyDB tinyDB;
RestAdapter restAdapter;
private static int radius = Utils.dpToPx(28);
private LayoutInflater mInflater;
Galleri5Application application;
MixpanelAPI mixpanel;
private static final int ITEM_TYPE_HEADER = 0, ITEM_TYPE_CARD = 1, ITEM_TYPE_RIBBON = 2, ITEM_TYPE_LOADING = 3;
public StickyFeedAdapter(Context context, List<FeedItems> list, Fragment fragment) {
this.context = context;
this.feedItems = list;
this.fragment = fragment;
mInflater = LayoutInflater.from(context);
application = (Galleri5Application) ((AppCompatActivity) context).getApplication();
API = application.getAPI();
mixpanel = MixpanelAPI.getInstance(context, application.getMixpanelId());
OkHttpClient okHttpClient = new OkHttpClient();
tinyDB = new TinyDB(context);
token = tinyDB.getString(AppConstants.GALLERI5_ACCESS_TOKEN);
RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", "Token " + token);
}
};
restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(API)
.setRequestInterceptor(requestInterceptor)
.build();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LogUtil.i(TAG, "onCreateViewHolder called");
if (viewType == ITEM_TYPE_HEADER) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_row, parent, false);
return new HeaderViewHolder(view);
} else if (viewType == ITEM_TYPE_CARD) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_new_card, parent, false);
return new CardViewHolder(view);
} else if (viewType == ITEM_TYPE_RIBBON) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_row_ribbon, parent, false);
return new RibbonViewHolder(view, context);
} else if (viewType == ITEM_TYPE_LOADING) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_loading, parent, false);
return new LoadingViewHolder(view);
} else {
return null;
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
LogUtil.i(TAG, "onBindViewHolder called");
int viewType = getItemViewType(position);
FeedItems currentItem = getItem(position);
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
if (viewType == ITEM_TYPE_HEADER) {
final HeaderItem headerItem = currentItem.getHeaderItem();
layoutParams.setFullSpan(true);
if (headerItem.isFollowing()) {
((HeaderViewHolder) holder).mightLike.setVisibility(View.GONE);
((HeaderViewHolder) holder).followButton.setBackgroundResource(R.drawable.button_background_filled);
((HeaderViewHolder) holder).followText.setTextColor(Color.parseColor("#424447"));
((HeaderViewHolder) holder).followText.setText("FOLLOWING");
} else {
((HeaderViewHolder) holder).mightLike.setVisibility(View.VISIBLE);
((HeaderViewHolder) holder).followButton.setBackgroundResource(R.drawable.button_background);
((HeaderViewHolder) holder).followText.setTextColor(Color.parseColor("#F0F0E9"));
((HeaderViewHolder) holder).followText.setText("FOLLOW");
}
((HeaderViewHolder) holder).followButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!headerItem.isFollowing()) {
//follow gallery
headerItem.setFollowing(true);
((HeaderViewHolder) holder).mightLike.setVisibility(View.GONE);
((HeaderViewHolder) holder).followButton.setBackgroundResource(R.drawable.button_background_filled);
((HeaderViewHolder) holder).followText.setTextColor(Color.parseColor("#424447"));
((HeaderViewHolder) holder).followText.setText("FOLLOWING");
follow(headerItem.getGalleryPk());
} else {
//unfollow gallery
headerItem.setFollowing(false);
((HeaderViewHolder) holder).mightLike.setVisibility(View.VISIBLE);
((HeaderViewHolder) holder).followButton.setBackgroundResource(R.drawable.button_background);
((HeaderViewHolder) holder).followText.setTextColor(Color.parseColor("#F0F0E9"));
((HeaderViewHolder) holder).followText.setText("FOLLOW");
unfollow(headerItem.getGalleryPk());
}
}
});
((HeaderViewHolder) holder).shareButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
((HeaderViewHolder) holder).galleryName.setText(headerItem.getGalleryName());
((HeaderViewHolder) holder).numPhotos.setText(String.format("%s PHOTOS", String.valueOf(headerItem.getNumPhotos())));
((HeaderViewHolder) holder).numFollowers.setText(String.format("%s FOLLOWERS", String.valueOf(headerItem.getNumFollowers())));
} else if (viewType == ITEM_TYPE_CARD) {
final FeedPhoto cardItem = currentItem.getCardItem();
layoutParams.setFullSpan(false);
double aspectRatio = (double) cardItem.getWidth() / cardItem.getHeight();
((CardViewHolder) holder).image.setAspectRatio((float) aspectRatio);
Uri uri = Uri.parse(cardItem.getPhotoUrl());
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setProgressiveRenderingEnabled(true)
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(((CardViewHolder) holder).image.getController())
.build();
((CardViewHolder) holder).image.setController(controller);
Picasso.with(context)
.load(cardItem.getProfilePic())
.resize(radius, radius)
.centerCrop()
.transform(new CircleTransform())
.into(((CardViewHolder) holder).profilePic);
((CardViewHolder) holder).username.setText(cardItem.getUserName());
((CardViewHolder) holder).timestamp.setText(cardItem.getTime());
if (TextUtils.isEmpty(cardItem.getLocation())) {
((CardViewHolder) holder).locationBox.setVisibility(View.GONE);
} else {
((CardViewHolder) holder).locationBox.setVisibility(View.VISIBLE);
((CardViewHolder) holder).locationText.setText(cardItem.getLocation());
}
if (TextUtils.isEmpty(cardItem.getCaption())) {
((CardViewHolder) holder).captionText.setVisibility(View.GONE);
} else {
((CardViewHolder) holder).captionText.setVisibility(View.VISIBLE);
((CardViewHolder) holder).captionText.setText(cardItem.getCaption());
}
((CardViewHolder) holder).collectButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, AddToCollectionActivity.class);
intent.putExtra("photoPk", cardItem.getPk());
intent.putExtra("imageUrl", cardItem.getPhotoUrl());
intent.putExtra("location", cardItem.getLocation());
intent.putExtra("caption", cardItem.getCaption());
context.startActivity(intent);
((Activity) context).overridePendingTransition(R.anim.slide_up, R.anim.no_change);
}
});
} else if (viewType == ITEM_TYPE_RIBBON) {
RibbonItem ribbonItem = currentItem.getRibbonItem();
layoutParams.setFullSpan(true);
FeedRibbonAdapter feedRibbonAdapter = new FeedRibbonAdapter(context, fragment, ribbonItem);
((RibbonViewHolder) holder).feedRibbonAdapter = feedRibbonAdapter;
((RibbonViewHolder) holder).ribbonText.setText(ribbonItem.getTitle());
((RibbonViewHolder) holder).recyclerView.setAdapter(feedRibbonAdapter);
} else if (viewType == ITEM_TYPE_LOADING) {
layoutParams.setFullSpan(true);
((LoadingViewHolder) holder).indicator.setVisibility(View.VISIBLE);
}
}
public FeedItems getItem(int position) {
return feedItems.get(position);
}
@Override
public int getItemViewType(int position) {
LogUtil.i(TAG, "getItemViewType called");
FeedItems currentItem = getItem(position);
if (currentItem.getType() == 0) {
return ITEM_TYPE_HEADER;
} else if (currentItem.getType() == 1) {
return ITEM_TYPE_CARD;
} else if (currentItem.getType() == 2) {
return ITEM_TYPE_RIBBON;
} else {
return ITEM_TYPE_LOADING;
}
}
@Override
public int getItemCount() {
return feedItems == null ? 0 : feedItems.size();
}
@Override
public long getHeaderId(int position) {
LogUtil.i(TAG, "getHeaderId called");
if (position == 0) { // don't show header for first item
return StickyHeaderDecoration.NO_HEADER_ID;
} else {
return getHeaderForPosition(position);
}
}
private long getHeaderForPosition(int position) {
for (int i = position; i > 0; i--) {
if (getItem(position) != null) {
if (getItem(position).getType() == 0) {
return (long) i;
}
}
}
return StickyHeaderDecoration.NO_HEADER_ID;
}
@Override
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
LogUtil.i(TAG, "onCreateHeaderViewHolder called");
View view = mInflater.inflate(R.layout.feed_row, parent, false);
return new HeaderViewHolder(view);
}
@Override
public void onBindHeaderViewHolder(final HeaderViewHolder viewholder, int position) {
LogUtil.i(TAG, "onBindHeaderViewHolder called");
FeedItems currentItem = getItem(position);
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) viewholder.itemView.getLayoutParams();
final HeaderItem headerItem = currentItem.getHeaderItem();
layoutParams.setFullSpan(true);
if (headerItem.isFollowing()) {
viewholder.mightLike.setVisibility(View.GONE);
viewholder.followButton.setBackgroundResource(R.drawable.button_background_filled);
viewholder.followText.setTextColor(Color.parseColor("#424447"));
viewholder.followText.setText("FOLLOWING");
} else {
viewholder.mightLike.setVisibility(View.VISIBLE);
viewholder.followButton.setBackgroundResource(R.drawable.button_background);
viewholder.followText.setTextColor(Color.parseColor("#F0F0E9"));
viewholder.followText.setText("FOLLOW");
}
viewholder.followButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!headerItem.isFollowing()) {
//follow gallery
headerItem.setFollowing(true);
viewholder.mightLike.setVisibility(View.GONE);
viewholder.followButton.setBackgroundResource(R.drawable.button_background_filled);
viewholder.followText.setTextColor(Color.parseColor("#424447"));
viewholder.followText.setText("FOLLOWING");
follow(headerItem.getGalleryPk());
} else {
//unfollow gallery
headerItem.setFollowing(false);
viewholder.mightLike.setVisibility(View.VISIBLE);
viewholder.followButton.setBackgroundResource(R.drawable.button_background);
viewholder.followText.setTextColor(Color.parseColor("#F0F0E9"));
viewholder.followText.setText("FOLLOW");
unfollow(headerItem.getGalleryPk());
}
}
});
viewholder.shareButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
viewholder.galleryName.setText(headerItem.getGalleryName());
viewholder.numPhotos.setText(String.format("%s PHOTOS", String.valueOf(headerItem.getNumPhotos())));
viewholder.numFollowers.setText(String.format("%s FOLLOWERS", String.valueOf(headerItem.getNumFollowers())));
}
private void follow(int galleryPk) {
LogUtil.i(TAG, "follow called");
PostAPI api = restAdapter.create(PostAPI.class);
api.follow(galleryPk, new Callback<ActionResponse>() {
@Override
public void success(ActionResponse actionResponse, Response response) {
LogUtil.i(TAG, "follow successful");
}
@Override
public void failure(RetrofitError error) {
LogUtil.i(TAG, "follow failed");
}
});
}
private void unfollow(int galleryPk) {
LogUtil.i(TAG, "unfollow called");
PostAPI api = restAdapter.create(PostAPI.class);
api.unfollow(galleryPk, new Callback<ActionResponse>() {
@Override
public void success(ActionResponse actionResponse, Response response) {
LogUtil.i(TAG, "unfollow successful");
}
@Override
public void failure(RetrofitError error) {
LogUtil.i(TAG, "unfollow failed");
}
});
}
public static class HeaderViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.mightLike)
TextView mightLike;
@Bind(R.id.galleryName)
TextView galleryName;
@Bind(R.id.shareButton)
RelativeLayout shareButton;
@Bind(R.id.shareText)
TextView shareText;
@Bind(R.id.followButton)
RelativeLayout followButton;
@Bind(R.id.followText)
TextView followText;
@Bind(R.id.numPhotos)
TextView numPhotos;
@Bind(R.id.numFollowers)
TextView numFollowers;
public HeaderViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
public static class CardViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.profilePic)
ImageView profilePic;
@Bind(R.id.username)
TextView username;
@Bind(R.id.timestamp)
TextView timestamp;
@Bind(R.id.image)
SimpleDraweeView image;
@Bind(R.id.tagButton)
ImageView tagButton;
@Bind(R.id.reminderButton)
ImageView reminderButton;
@Bind(R.id.collectButton)
RelativeLayout collectButton;
@Bind(R.id.shareButton)
RelativeLayout shareButton;
@Bind(R.id.locationBox)
LinearLayout locationBox;
@Bind(R.id.locationText)
TextView locationText;
@Bind(R.id.captionText)
TextView captionText;
public CardViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
public static class RibbonViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.recyclerView)
FlingRecyclerView recyclerView;
@Bind(R.id.ribbonText)
TextView ribbonText;
FeedRibbonAdapter feedRibbonAdapter;
public RibbonViewHolder(View view, Context context) {
super(view);
ButterKnife.bind(this, view);
LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);
SpacesItemDecoration spacesItemDecoration = new SpacesItemDecoration(Utils.dpToPx(8));
recyclerView.addItemDecoration(spacesItemDecoration);
}
}
public static class LoadingViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.avloadingIndicatorView)
AVLoadingIndicatorView indicator;
public LoadingViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
private static class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
int count = state.getItemCount();
if (position == 0) {
outRect.left = space;
outRect.right = space / 2;
} else if (position == count - 1) {
outRect.right = space;
outRect.left = space / 2;
} else {
outRect.left = space / 2;
outRect.right = space / 2;
}
}
}
}
I see that the getHeaderId() is never called. I have one type of view which will be header and 3 other view types that would not be header and won't stick. What's wrong with my implementation?