Android RecyclerView with different CardViews

来源:互联网 时间:1970-01-01

Cards are great for lists with heterogeneous content. And RecyclerView is recommended over ListView for data collections that change at run-time. Let’s see how to use these together to create a RecyclerView with multiple CardViews.

This is the output:

Weather, Score and News cards

There are three types of cards namely weather, news & score card. The key for implementation lies with the getItemViewType method in RecyclerView.Adapter . The default implementation of this method returns 0, making the assumption of a single view type for the adapter. We need to override it and provide item type for each item.

Create three view types for the three cards:

public static final int WEATHER = 0;public static final int SCORE = 1;public static final int NEWS = 2;

Note:It is recommended to use ID resources to identify the card types.

Dependencies

First step is to include the dependencies in your build.grade:

compile 'com.android.support:cardview-v7:23.0.1'compile 'com.android.support:recyclerview-v7:23.0.1' Set up RecyclerView

In activity xml:

<android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/>

In activity:

private RecyclerView mRecyclerView;private CustomAdapter mAdapter;private RecyclerView.LayoutManager mLayoutManager;private String[] mDataset = {"29 degrees", "Seahawks 24 - 27 Bengals", "Flash missing, vanishes in crisis", "Half Life 3 announced"};private int mDatasetTypes[] = {WEATHER, SCORE, NEWS, NEWS}; //view types...mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);mLayoutManager = new LinearLayoutManager(MainActivity.this);mRecyclerView.setLayoutManager(mLayoutManager);//Adapter is created in the last stepmAdapter = new CustomAdapter(mDataset);mRecyclerView.setAdapter(mAdapter); Create the CardViews

weather_card.xml

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cardview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:elevation="100dp" card_view:cardBackgroundColor="#607D8B"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Weather" android:textColor="#ffffff" /> <TextView android:id="@+id/temp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:textColor="#ffffff" android:textSize="30sp" /> </LinearLayout></android.support.v7.widget.CardView>

score_card.xml

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cardview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:elevation="100dp" card_view:cardBackgroundColor="#00bcd4"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Score" android:textColor="#ffffff" /> <TextView android:id="@+id/score" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:textColor="#ffffff" android:textSize="30sp" /> </LinearLayout></android.support.v7.widget.CardView>

news_card.xml

<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/cardview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:elevation="100dp" card_view:cardBackgroundColor="#fff"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="News" /> <TextView android:id="@+id/headline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:textSize="25sp" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:id="@+id/read_more" android:background="#fff" android:text="Read More" /> </LinearLayout></android.support.v7.widget.CardView> Create Adapter

Three ViewHolders are needed, one for each type of the card and they all inherit from a generic ViewHolder class. In onCreateViewHolder check for view type and inflate the corresponding card xml. In onBindViewHolder again check the view type and set data to the views.

Here’s the full adapter class:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private static final String TAG = "CustomAdapter"; private String[] mDataSet; private int[] mDataSetTypes; public static final int WEATHER = 0; public static final int SCORE = 1; public static final int NEWS = 2; public static class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View v) { super(v); } } public class WeatherViewHolder extends ViewHolder { TextView temp; public WeatherViewHolder(View v) { super(v); this.temp = (TextView) v.findViewById(R.id.temp); } } public class ScoreViewHolder extends ViewHolder { TextView score; public ScoreViewHolder(View v) { super(v); this.score = (TextView) v.findViewById(R.id.score); } } public class NewsViewHolder extends ViewHolder { TextView headline; Button read_more; public NewsViewHolder(View v) { super(v); this.headline = (TextView) v.findViewById(R.id.headline); this.read_more = (Button) v.findViewById(R.id.read_more); } } public CustomAdapter(String[] dataSet, int[] dataSetTypes) { mDataSet = dataSet; mDataSetTypes = dataSetTypes; } @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { View v; if (viewType == WEATHER) { v = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.weather_card, viewGroup, false); return new WeatherViewHolder(v); } else if (viewType == NEWS) { v = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.news_card, viewGroup, false); return new NewsViewHolder(v); } else { v = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.score_card, viewGroup, false); return new ScoreViewHolder(v); } } @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { if (viewHolder.getItemViewType() == WEATHER) { WeatherViewHolder holder = (WeatherViewHolder) viewHolder; holder.temp.setText(mDataSet[position]); } else if (viewHolder.getItemViewType() == NEWS) { NewsViewHolder holder = (NewsViewHolder) viewHolder; holder.headline.setText(mDataSet[position]); } else { ScoreViewHolder holder = (ScoreViewHolder) viewHolder; holder.score.setText(mDataSet[position]); } } @Override public int getItemCount() { return mDataSet.length; } @Override public int getItemViewType(int position) { return mDataSetTypes[position]; }}

相关阅读:
Top