If you’re writing a new Android app, and a list of cards make sense for your layout, chances are you want to look at the new RecyclerView and CardView. This post is a quick tutorial about how to use them.
When we’re done here (in 15 minutes), we should have this simple app built:
First, just to get familiar with cards, we can create a simple card. This will do:
<android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- Content inside the card. --> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" > <!-- A photo on the left. We'll just use the launcher icon. --> <ImageView android:id="@+id/person_photo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:src="@mipmap/ic_launcher" tools:ignore="ContentDescription" /> <!-- The person name, on top --> <TextView android:id="@+id/person_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toEndOf="@+id/person_photo" android:layout_toRightOf="@+id/person_photo" android:layout_alignParentTop="true" android:textSize="30sp" android:text="Emma Wilson" tools:ignore="HardcodedText" /> <!-- The age, in the bottom --> <TextView android:id="@+id/person_age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toEndOf="@+id/person_photo" android:layout_toRightOf="@+id/person_photo" android:layout_below="@+id/person_name" android:text="23 years old" tools:ignore="HardcodedText" /> </RelativeLayout> </android.support.v7.widget.CardView>
Pretty straight-forward, right? In our example GitHub repo, this is done in this changeset, check out that version for a minimalistic working example project.
Now let’s create a recycler view (that is, a modern listview, so to speak) with a bunch of cards. Follow this changeset for the details.
First, we need an adapter, to provide the data. What’s special about the adapter for a recycler view is that it provides built-in support for the view holder. Note that we’re gonna use the view holder, and provide it with a layout for every card:
class QuizListAdapter extends RecyclerView.Adapter { private final List quizzes; QuizListAdapter(List quizzes) { this.quizzes = quizzes; } @Override public QuizViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { final LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext()); final View v = layoutInflater.inflate(R.layout.quiz_card, viewGroup, false); // Layout for every card return new QuizViewHolder(v); // View holder } @Override public void onBindViewHolder(QuizViewHolder quizViewHolder, int i) { quizViewHolder.quizQuestion.setText(quizzes.get(i).getQuestion()); } @Override public int getItemCount() { return quizzes.size(); } }
Here’s our view holder for a very simple card:
class QuizViewHolder extends RecyclerView.ViewHolder { TextView quizQuestion; QuizViewHolder(View itemView) { super(itemView); quizQuestion = (TextView) itemView.findViewById(R.id.quiz_question); } }
And the layout for every item in the recycler view, a very simple card:
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/quiz_question" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </android.support.v7.widget.CardView>
Lastly, we hook up the adapter into the recycler view, with an intuitive myRecyclerView.setAdapter(new QuizListAdapter());
.
And that’s pretty much it!