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); } }