I\'m trying to implement the below image. My first thought was to have everything above the grid layout be the first row of the grid and use SpanSizeLookup to set the span s
What kind of problems are you anticipating from SpanSizeLookup? You can implement it with a few lines as follows (I'd recommend using values from integers.xml for flexibility).
GridLayoutManager glm = new GridLayoutManager(getContext(), 3);
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override public int getSpanSize(int position) {
return (position == 0) ? 3 : 1;
}
});
If your header layout needs views and fields that your regular layout doesn't have, you'll want to create separate views and tell your adapter about them. Something like this.
@Override
public int getItemViewType(int position) {
if (position == 0)
return TYPE_HEADER;
else
return TYPE_REGULAR;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
MyHeaderView view = (MyHeaderView) LayoutInflater
.from(parent.getContext())
.inflate(R.layout.my_header_view, parent, false);
return new MyHeaderViewHolder(view);
} else {
MyRegularView view = (MyRegularView) LayoutInflater
.from(parent.getContext())
.inflate(R.layout.my_regular_view, parent, false);
return new MyRegularViewHolder(view);
}
}
An example header view could be like this (you'd call bindTo()
from MyHeaderViewHolder
).
public final class MyHeaderView extends LinearLayout {
@Bind(R.id.image) ImageView imageView;
@Bind(R.id.title) TextView titleView;
public MyHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
ButterKnife.bind(this);
}
public void bindTo(String imageUrl, String title) {
Glide.with(getContext())
.load(imageUrl).into(imageView);
titleView.setText(title);
}
}
This makes the item as wide as the RecyclerView itself (similar to match_parent).
Set various click listeners in the specific ViewHolder that's responsible for this item. Using this approach would set the whole complex view to behave (scroll) as part of the RecyclerView while still making it available for (input) events.
You could have a look at Bookends
Or another(the way i usually do it) way would be to use a GridLayouManager with a SpanSizeLookUp. And use multiple ViewTypes i.e. one for Header,Footer and Items.
Go for 1 if you have only a single header and what a ListView-ish interface in your code.
Go for 2 if you are not sure about how many Custom ViewTypes you would be adding.It assures you have maximum scalability in the future.
If you are considering massive scalability,I suggest you read this article by Hannes Dorfman .