こんにちは、やぎにいです!
やぎすけ Advent Calendar 2016の3日目です。今のところ順調ですね。
2日目に昨日はうなすけがやぎすけ Advent Calendar 2日目 Gemfileの整頓を書いてくれました。
ここに出てきたRailsアプリはアドベントカレンダー後半で数日に渡って公開していきたいと思います。
Androidにはリストを表示するときにListView
なり、GridView
なりありますがAndroidのサポートライブラリv7で提供されているより柔軟なものがRecyclerView
になります。(ざっくり)
ListView
やGridView
表示を行えるのですが、じゃあそれらと何が違うの?と言うとそれらと比べて自由にカスタマイズできるという点があります。
ListView
,GridView
で解決できないような物などに出会った際RecyclerView
を使うのが良いと思います。
単純にListView
などで十分な場合はそれでいいと思いますが、個人的にあとで「あーやっぱRecyclerView
にしとけばよかった」みたいになった時に面倒なので、最近は最初からこちらを使うようにしています。
「カスタマイズ性が高い」ので最初最小構成でRecyclerView
を構築した際にはリストのアイテム間の区切り(devider)が無いなどありますが、この記事ではそういうカスタマイズを省いて最小構成でサクッとRecyclerView
を実装してアイテムを表示する流れを紹介します。
今回はNexus 5X(Android 7.1.1)で実機実行をしています。
app/build.gradle
のdependencies
に
1 | compile 'com.android.support:recyclerview-v7:25.0.1' |
を追加します。
Android Studioを使用している場合は、appを右クリックするとOpen Module Settings
があるのでそこからrecyclerview
で検索するとライブラリが存在すると思います。
書くものは2つです
RecyclerView
本体RecyclerView
のアイテムのレイアウト順番にやっていきましょう
まず、RecyclerView
本体。これは実際に配置したい場所に書いてあげます。
今回はlayout/activity_main.xml
の中に書きました。
1 2 3 4 | <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> |
次にRecyclerView
内のアイテムのレイアウトです、今回はTextView
だけ配置します。
1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Large"/> </LinearLayout> |
今回これはlayout/list_item.xml
として配置しました。
以上でレイアウトの準備は完了です。
続いてAdapter
を作成します。 まず完成形をペタッと。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { private LayoutInflater mInflater; private ArrayList<String> mData; private Listener mListener; // アイテムタップ用interface public interface Listener { void onRecyclerClicked(View v, int position); } public RecyclerViewAdapter(Context context, ArrayList<String> data, Listener listener) { mInflater = LayoutInflater.from(context); mData = data; mListener = listener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ViewHolder(mInflater.inflate(R.layout.list_item, parent, false)); } @Override public void onBindViewHolder(ViewHolder holder, final int position) { holder.textView.setText(mData.get(position)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mListener.onRecyclerClicked(view, position); } }); } @Override public int getItemCount() { if (mData == null) { return 0; } else { return mData.size(); } } // ViewHolder public class ViewHolder extends RecyclerView.ViewHolder { TextView textView; public ViewHolder(View itemView) { super(itemView); textView = (TextView)itemView.findViewById(R.id.text); } } } |
継承するのはRecyclerView.Adapter<ViewHolder>
になります。今回はインナークラスRecyclerViewAdapter.ViewHolder
として実装しました。
TextView
しかアイテムが存在しないのでそれだけ書いてあげます。
アイテムをタップしたときのイベント用にinterface
を作成しています。RecyclerViewAdapter.Listener
として実装しています。
onRecyclerClicked()
としてタップされた場所とview
を引数として定義しています。
コンストラクタではコンテキストと実際のデータ(今回はTextView
に表示するためのArrayList<String>
)とインターフェースを受け取ってセットしています。
onCreateViewHolder
では先ほど作成したアイテムのレイアウトを指定して、ViewHolder
を作成しています。
onBindViewHolder
では実際にアイテムに受け取ったデータをセットして、イベントリスナーをセットしています。
タップイベント用のインターフェース、及びViewHolder
は別ファイルとしてもいいですが、この程度の規模であればクラス内に実装してあげて大丈夫でしょう。
Adapter
が完成したらあとはもうデータを渡してRecyclerView
にセットすれば完了です。
今回はFragment
ではなくActivity
(MainActivity)でやっていきます。
まず完成形をペタリ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.Listener { private RecyclerView mRecyclerView; private RecyclerViewAdapter mRecyclerViewAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = (RecyclerView)findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); ArrayList<String> data = new ArrayList<>(); data.add("うなすけ"); data.add("やぎにい"); data.add("アドベントカレンダー"); data.add("やっていき!"); mRecyclerViewAdapter = new RecyclerViewAdapter(this, data, this); mRecyclerView.setAdapter(mRecyclerViewAdapter); } @Override public void onRecyclerClicked(View v, int position) { TextView textView = (TextView)v.findViewById(R.id.text); Toast.makeText(this, textView.getText().toString(), Toast.LENGTH_SHORT).show(); } } |
必要なのは以下の部分。
1 2 3 4 5 6 7 8 9 10 11 12 | mRecyclerView = (RecyclerView)findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); //データの作成 ArrayList<String> data = new ArrayList<>(); data.add("うなすけ"); data.add("やぎにい"); data.add("アドベントカレンダー"); data.add("やっていき!"); mRecyclerViewAdapter = new RecyclerViewAdapter(this, data, this); mRecyclerView.setAdapter(mRecyclerViewAdapter); |
簡単ですね!基本的な感じはListView
やGridView
と変わりません。
このコードで実行するとListView
になりますが、GridView
にしたい場合は2行目の部分を
1 | mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2)); |
としてあげれば良いです。(第2引数はspanの数です)
さらに横方向にスクロールするようなリストにしたい場合は
1 2 3 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); mRecyclerView.setLayoutManager(linearLayoutManager); |
Activityは先ほどAdapterで作成したインターフェースをimplements
で渡してあげて、オーバーライドしてあげます。
今回はタップされたら、そのアイテムの文字をトーストで表示するような実装をしています。
1 2 3 4 5 6 7 8 9 | public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.Listener { ...省略... @Override public void onRecyclerClicked(View v, int position) { TextView textView = (TextView)v.findViewById(R.id.text); Toast.makeText(this, textView.getText().toString(), Toast.LENGTH_SHORT).show(); } } |
これでRecyclerViewの一通りの実装は完了です。
このままだと区切り線などがないので、必要な方は実装する形になります。
途中で横スクロールのリストを設定する際にLinearLayoutManager
を自分で作成したことからわかるように、こうやって自分で作成することよって様々にカスタマイズをすることが出来ます。
ListView
からGridView
に簡単に移行できるのも結構便利ですね。
いかがでしたでしょうか。僕も最初はとっつきにくいと思いListView
などで頑張っていたのですがやってみると意外と簡単に実装できてしまいます。
確かにそれらと比べて自前で実装しなければならないのがとても多いですが、意外ときれいに実装できるので最初にぐっと実装してしまえば以降は柔軟に使っていくことができると思います。
今回ここで紹介したコードはAndroid ProjectとしてGithubに公開しておきました。
yagi2/RecyclerView-sample
どなたかの参考に慣れれば幸いです。
以上、やぎにいでした!
<< Androidプロジェクトを作って結構な確率で導入するライブラリ やぎすけ Advent Calendar 2016 >>
2018やぎ小屋