RecyclerViewとは
主に、動的な件数のViewを繰り返し表示するためのWidget。
サポートライブラリのcom.android.support:recyclerview-v7で利用可能。
ListViewとの違い
RecyclerViewはListViewと異なり
- HeaderViewとFooterViewが無い
- 区切り線等のセル装飾は自分で実装しないといけない
- ListItemのクリックイベントが無いから自分で実装しないといけない
- ViewHolderが標準で組み込まれている
- addやremoveのアニメーションが簡単に付与できる
- 横スクロールやグリッド表示等が簡単に設定できる
等、様々な違いがある。
実装方法
通常の縦スクロールリストの簡単な作り方を記載。
セルには一行のテキストを表示するだけ。
Layout
まず画面にRecyclerViewを設置
〜省略〜
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
〜省略〜
次にリストのセルとなるレイアウトを作成(この辺りはListViewと一緒)
<?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/list_item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Fragment
初期化
public class RecyclerFragment extends Fragment implements OnRecyclerListener {
private Activity mActivity = null;
private View mView;
private RecyclerFragmentListener mFragmentListener = null;
// RecyclerViewとAdapter
private RecyclerView mRecyclerView = null;
private RecyclerAdapter mAdapter = null;
public interface RecyclerFragmentListener {
void onRecyclerEvent();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof RecyclerFragmentListener)) {
throw new UnsupportedOperationException(
"Listener is not Implementation.");
} else {
mFragmentListener = (RecyclerFragmentListener) activity;
}
mActivity = activity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment, container, false);
// RecyclerViewの参照を取得
mRecyclerView = (RecyclerView) mView.findViewById(R.id.recycler_view);
// レイアウトマネージャを設定(ここで縦方向の標準リストであることを指定)
mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
return mView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// 適当にデータ作成
ArrayList<String> array = new ArrayList<>();
array.add("A");
array.add("B");
array.add("C");
// この辺りはListViewと同じ
// 今回は特に何もしないけど、一応クリック判定を取れる様にする
mAdapter = new RecyclerAdapter(mActivity, array, this);
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void onRecyclerClicked(View v, int position) {
// セルクリック処理
}
Listener
OnItemClickListenerとかが無いので、自分が取りたい情報が取れる様に勝手に作る。
public interface OnRecyclerListener {
void onRecyclerClicked(View v, int position);
}
Adapter
ListViewと同様にAdapterも実装する
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private LayoutInflater mInflater;
private ArrayList<String> mData;
private Context mContext;
private OnRecyclerListener mListener;
public RecyclerAdapter(Context context, ArrayList<String> data, OnRecyclerListener listener) {
mInflater = LayoutInflater.from(context);
mContext = context;
mData = data;
mListener = listener;
}
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
// 表示するレイアウトを設定
return new ViewHolder(mInflater.inflate(R.layout.list_item, viewGroup, false));
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int i) {
// データ表示
if (mData != null && mData.size() > i && mData.get(i) != null) {
viewHolder.textView.setText(mData.get(i));
}
// クリック処理
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onRecyclerClicked(v, i);
}
});
}
@Override
public int getItemCount() {
if (mData != null) {
return mData.size();
} else {
return 0;
}
}
// ViewHolder(固有ならインナークラスでOK)
class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.list_item_text);
}
}
}
ここまででひとまずリスト表示までは完成。
Tips
セルのレイアウトを切り替えたい
getItemViewTypeでデータによって異なるViewTypeを返却し、AdapterのonCreateViewHolderで
returnするViewHolderを変更すればOK。
まったく異なるレイアウトを切り替えることになるなら、ViewHolderも分けた方が良い。
Stringリストで
「Header」が入っていればヘッダ
「Footer」が入っていればフッタ
それ以外はデータ
という切替を行う場合
private final static int VIEWTYPE_HEADER = 1;
private final static int VIEWTYPE_FOOTER = 2;
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
switch (i) {
case VIEWTYPE_HEADER:
return new HeaderViewHolder(mLayoutInflater
.inflate(R.layout.list_item_header, viewGroup, false));
case VIEWTYPE_FOOTER:
return new FooterViewHolder(mLayoutInflater
.inflate(R.layout.list_item_footer, viewGroup, false));
default:
return new DataViewHolder(mLayoutInflater
.inflate(R.layout.list_item_data, viewGroup, false));
}
}
@Override
public int getItemViewType(int position) {
if (mData.get(position).equals("Header")) {
return VIEWTYPE_HEADER;
} else if (mData.get(position).equals("Footer")) {
return VIEWTYPE_FOOTER;
} else {
return 0;
}
}
class ViewHolder extends RecyclerView.ViewHolder {
// 基底になるViewHolder
}
class HeaderViewHolder extends RecyclerAdapter.ViewHolder {
// ヘッダのViewHolder
}
class FooterViewHolder extends RecyclerAdapter.ViewHolder {
// フッタのViewHolder
}
class DataViewHolder extends RecyclerAdapter.ViewHolder {
// データのViewHolder
}
こんな感じで切り替えられる
横スクロールリストを作りたい
setLayoutManagerでセットするレイアウトマネージャの設定を変更する
LinearLayoutManager manager = new LinearLayoutManager(mActivity);
manager.setOrientation(LinearLayoutManager.HORIZONTAL); // ここで横方向に設定
mRecyclerView.setLayoutManager(manager);
グリッド表示リストを作りたい
setLayoutManagerでセットするレイアウトマネージャの種類を変更する
// GridLayoutManagerの第二引数は、X方向の件数
mRecyclerView.setLayoutManager(new GridLayoutManager(mActivity, 2));