I’ve implemented simple HelloWorld app, which shows list of cities and based on how many museums it has – shows full-sized city-card or the centered, wrapped version of it.

(Yes, I’m not exactly good at arts 🙂 )
Here’s how I did it.
TL;DR:
The crucial part is ItemDecoration: set proper items offset and you’ll get what you need; Here’s how I’ve done it:
RecyclerView recyclerViewMuseum = (RecyclerView)findViewById(R.id.recyclerViewMuseum);
recyclerViewMuseum.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recyclerViewMuseum.setAdapter(adapter);
recyclerViewMuseum.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (view instanceof CityWithOneMuseumCardView) {
int totalWidth = parent.getWidth();
int cardWidth = getResources().getDimensionPixelOffset(R.dimen.small_card_width);
int sidePadding = (totalWidth - cardWidth) / 2;
sidePadding = Math.max(0, sidePadding);
outRect.set(sidePadding, 0, sidePadding, 0);
}
}
});
Here’s my model – City and Museum classes:
public class Museum {
public String title;
public Museum(String title) {
this.title = title;
}
}
public class City {
public String title;
public int imageRes;
public List<Museum> museums = new ArrayList<>();
public City(String title, int imageRes) {
this.title = title;
this.imageRes = imageRes;
}
}
Then Views: CityWithManyMuseumsCardView and CityWithOneMuseumCardView. Both of them are using helper-interface IItemDisplayer.
public class CityWithOneMuseumCardView extends CardView implements IItemDisplayer<City> {
public CityWithOneMuseumCardView(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.one_museum_layout, this);
}
@Override
public void displayItem(City city) {
TextView cityTitleTextView = (TextView)findViewById(R.id.cityTitleTextView);
cityTitleTextView.setText(city.title);
}
}
public class CityWithManyMuseumsCardView extends CardView implements IItemDisplayer<City> {
public CityWithManyMuseumsCardView(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.many_museums_layout, this);
}
@Override
public void displayItem(City city) {
ImageView cityBackgroundImageView = (ImageView)findViewById(R.id.cityBackgroundImageView);
cityBackgroundImageView.setImageResource(city.imageRes);
TextView cityTitleTextView = (TextView)findViewById(R.id.cityTitleTextView);
cityTitleTextView.setText(city.title);
TextView cityNumberOrMuseumsTextView = (TextView)findViewById(R.id.cityNumberOrMuseumsTextView);
cityNumberOrMuseumsTextView.setText(String.valueOf(city.museums.size()));
}
}
public interface IItemDisplayer<TItem> {
public void displayItem(TItem item);
}
And their layouts :
<!-- One Museum card -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#BB2050AB"
android:layout_width="@dimen/small_card_width"
android:layout_height="200dp">
<TextView
android:background="#AA000000"
android:textColor="#FFFFFF"
android:text="Only one museum available"
android:textSize="16sp"
android:padding="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/cityTitleTextView"
android:layout_gravity="bottom"
android:background="#AAFFFFFF"
android:textColor="#000000"
android:textSize="24sp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="48dp" />
</FrameLayout>
<!-- Many museums card -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="240dp">
<ImageView
android:id="@+id/cityBackgroundImageView"
android:scaleType="fitXY"
android:layout_width="500dp"
android:layout_height="match_parent" />
<TextView
android:id="@+id/cityNumberOrMuseumsTextView"
android:layout_gravity="top|end"
android:background="#AA000000"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:padding="4dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/cityTitleTextView"
android:layout_gravity="bottom"
android:background="#AA000000"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="48dp" />
</FrameLayout>
Then we need to create an adapter for our RecyclerView
CityAdapter.java
public class CityAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final static int ITEM_TYPE_MANY_MUSEUMS = 0;
final static int ITEM_TYPE_ONE_MUSEUM = 1;
private List<City> items;
public CityAdapter(List<City> items) {
this.items = items;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType) {
case ITEM_TYPE_MANY_MUSEUMS:
return new ViewHolder(new CityWithManyMuseumsCardView(viewGroup.getContext()));
case ITEM_TYPE_ONE_MUSEUM:
return new ViewHolder(new CityWithOneMuseumCardView(viewGroup.getContext()));
default:
throw new IllegalArgumentException(String.format("Unexpected viewType: %d", viewType));
}
}
@Override
public int getItemViewType(int position) {
if (items == null || items.size() < position) {
throw new IllegalArgumentException("Wrong position!");
}
if (items.get(position).museums.size() > 1) {
return ITEM_TYPE_MANY_MUSEUMS;
} else if (items.get(position).museums.size() == 1){
return ITEM_TYPE_ONE_MUSEUM;
}
throw new IllegalArgumentException("Wrong number of museums!");
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((IItemDisplayer<City>) holder.itemView).displayItem(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
}
I’ve uploaded this project to my dropbox – feel free to check it out! Hope, it helps.