284
298

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Android】RecyclerViewの基本的な実装

Last updated at Posted at 2015-08-13

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

284
298
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
284
298

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?