Edited at

【Android】RecyclerViewの基本的な実装

More than 3 years have passed since last update.


RecyclerViewとは

主に、動的な件数のViewを繰り返し表示するためのWidget。

サポートライブラリのcom.android.support:recyclerview-v7で利用可能。


ListViewとの違い

RecyclerViewはListViewと異なり


  • HeaderViewとFooterViewが無い

  • 区切り線等のセル装飾は自分で実装しないといけない

  • ListItemのクリックイベントが無いから自分で実装しないといけない

  • ViewHolderが標準で組み込まれている

  • addやremoveのアニメーションが簡単に付与できる

  • 横スクロールやグリッド表示等が簡単に設定できる

等、様々な違いがある。


実装方法

通常の縦スクロールリストの簡単な作り方を記載。

セルには一行のテキストを表示するだけ。


Layout

まず画面にRecyclerViewを設置


fragment.xml

〜省略〜

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

〜省略〜


次にリストのセルとなるレイアウトを作成(この辺りはListViewと一緒)


list_item.xml

<?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

初期化


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とかが無いので、自分が取りたい情報が取れる様に勝手に作る。


OnRecyclerListener.java


public interface OnRecyclerListener {

void onRecyclerClicked(View v, int position);

}



Adapter

ListViewと同様にAdapterも実装する


RecyclerAdapter.java


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);
}
}

}


ここまででひとまずリスト表示までは完成。

recycler_sample_img_01.png


Tips


セルのレイアウトを切り替えたい

getItemViewTypeでデータによって異なるViewTypeを返却し、AdapterのonCreateViewHolderで

returnするViewHolderを変更すればOK。

まったく異なるレイアウトを切り替えることになるなら、ViewHolderも分けた方が良い。

Stringリストで

「Header」が入っていればヘッダ

「Footer」が入っていればフッタ

それ以外はデータ

という切替を行う場合


RecyclerAdapter.java


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でセットするレイアウトマネージャの設定を変更する


Fragment

        LinearLayoutManager manager = new LinearLayoutManager(mActivity);

manager.setOrientation(LinearLayoutManager.HORIZONTAL); // ここで横方向に設定
mRecyclerView.setLayoutManager(manager);



グリッド表示リストを作りたい

setLayoutManagerでセットするレイアウトマネージャの種類を変更する


Fragment

        // GridLayoutManagerの第二引数は、X方向の件数

mRecyclerView.setLayoutManager(new GridLayoutManager(mActivity, 2));


device-2015-08-18-104111.png