[Android Google I/O 2014] RecyclerView
Google I/O 2014で紹介されたAndroid Lのマテリアルデザイン「Material Design」で紹介された新しいUI Widgetの1つ「RecyclerView」について紹介していきます。
開発環境はEclipse+ADTではなく、Android Studioを使っています。
Eclipseではなんだかうまくできず(バージョン22でもあったMainActivity.javaとactivity_main.xmlが生成されないバグが、また現時点でのバージョン23でも起きているようです。これが関連しているのかもしれません。)、致し方なくAndroid Studioを使うことにしました。
参考ページ
http://developer.android.com/tools/support-library/setup.html
https://developer.android.com/preview/material/ui-widgets.html
2. build.gradleを変更します。サポートライブラリを参照できるようにすること(24行目)とcompileSdkVersionを変更します。(4行目)
サポートライブラリはSDKマネージャーでダウンロードしておいてください。
apply plugin: 'com.android.application'
android {
compileSdkVersion 'android-L'
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.example.recyclerviewsample"
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:recyclerview-v7:+'
}
SDK Managerでは「Android Support Repository」「Android Support Library」をダウンロードします。

3. activity_my.xmlを変更します。11行目のTextViewをRecyclerViewに変更します。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MyActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
4. 「MyActivity」クラスを変更します。この時点ではまだコンパイルエラーがでますが、気にしなくてOKです。
package com.example.recyclerviewsample;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
public class MyActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// コンテンツの変化でRecyclerViewのサイズが変わらない場合は、
// パフォーマンスを向上させることができる
mRecyclerView.setHasFixedSize(true);
// LinearLayoutManagerを使用する
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// テストデータを作成する
String[] myDataset = {"北海道",
"青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県",
"茨城県", "栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県",
"新潟県", "富山県", "石川県", "福井県", "山梨県", "長野県", "岐阜県", "静岡県", "愛知県",
"三重県", "滋賀県", "京都府", "大阪府", "兵庫県", "奈良県", "和歌山県",
"鳥取県", "島根県", "岡山県", "広島県", "山口県",
"徳島県", "香川県", "愛媛県", "高知県",
"福岡県", "佐賀県", "長崎県", "熊本県", "大分県", "宮崎県", "鹿児島県",
"沖縄県"};
// アダプタを指定する
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
}
}
5. 新しいクラス「MyAdapter」を作成します。ここでもコンパイルエラーがでますがOKです。
package com.example.recyclerviewsample;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;
// 使用しているビューの型への参照を渡す(カスタムViewHolder)
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(TextView v) {
super(v);
mTextView = v;
}
}
// 適切なコンストラクタを提供する(データセットの種類によって異なる)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// 新しいViewを作成する(レイアウトマネージャーによって起動される)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// 新しいViewを作成する
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, null);
// Viewのサイズ、余白、パディングなどのレイアウトパラメータを設定する
ViewHolder vh = new ViewHolder(v);
return vh;
}
// (レイアウトマネージャーによって起動される)Viewの内容を交換する
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// 1.データセットから要素を取得する
// 2.その要素とViewの内容を置き換える
holder.mTextView.setText(mDataset[position]);
}
// (レイアウトマネージャーによって起動される)データセットのサイズを返す
@Override
public int getItemCount() {
return mDataset.length;
}
}
6. 新しいレイアウトファイル「res/layout/my_text_view.xml」を作成します。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
</TextView>
これで全てのエラーが消えるはずです。
7. 最後に「Android L」のAVDを起動し、実行します。

今回は背景が「白」でしたので、いままでのListViewと見た目の違いがありませんでした。
プログラムの違いとしては、LinearLayoutManagerというクラスを新しく使わなくてはならない点と、RecyclerView.AdapterクラスがこれまでのAdapterクラスとは若干使い勝手が異なることでしょうか。
getItemCount()メソッドなど、これまでと同じように使えるものもある反面、目新しいメソッドもあるので慣れるまでは少し時間がかかりそうです。
レイアウトファイルでは、RecyclerViewがサポートライブラリに含まれるクラスということで、パッケージを含めたクラス名でタグを書かなければいけない点が基本ではありますがはまってしまうポイントかもしれません。
筆者としては、「Android Studio」を使うのが初めてということもあり、「build.gradle」の場所を勘違いしていたためにとても苦労してしまいました。プロジェクト直下にあるファイルではなく、「app」フォルダ以下にあるファイルを修正する必要があります。

次回(RecyclerViewの使い方(その2))は、RecyclerViewの目玉機能の1つである、Shadowをつけてみたいと思います。



