RecyclerView（縦） in RecyclerView（横）

※ [AdventCalendar Android その2](https://qiita.com/advent-calendar/2017/android_second) の一日目の記事です!

# RecyclerView in RecyclerViewでどんなことができる？
こんなことができる

<img src="https://qiita-image-store.s3.amazonaws.com/0/30138/d03ea088-4ac8-f7f1-6405-a7efdaa9f694.gif" width=50%>



# 方法

１、RecyclerViewのAdapterが管理しているViewHolder内で、新たに横用のRecyclerViewとAdapterを生成する

```java:MainActivity

public class MainActivity extends Activity {

    private RecyclerView mVerticalSampleRecyclerView;
    private VerticalRecyclerViewAdapter mVerticalRecyclerViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mVerticalSampleRecyclerView = findViewById(R.id.vertical_recycler_view);

        // LayoutManager
        LinearLayoutManager linearLayoutManager =
                new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false);
        mVerticalSampleRecyclerView.setLayoutManager(linearLayoutManager);

        // Adapter
        mVerticalRecyclerViewAdapter = new VerticalRecyclerViewAdapter();
        mVerticalSampleRecyclerView.setAdapter(mVerticalRecyclerViewAdapter);

        // リストをセット
        ArrayList<VerticalItem> verticalItems = new ArrayList<>();
        verticalItems.add(getVerticalItem());
        verticalItems.add(getVerticalItem());
        verticalItems.add(getVerticalItem());
        verticalItems.add(getVerticalItem());
        verticalItems.add(getVerticalItem());
        verticalItems.add(getVerticalItem());
        verticalItems.add(getVerticalItem());

        // リストセット・更新
        mVerticalRecyclerViewAdapter.setList(verticalItems);
        mVerticalRecyclerViewAdapter.notifyDataSetChanged();
    }

    private VerticalItem getVerticalItem() {
        ArrayList viewItems = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            viewItems.add(new ViewItem());
        }
        VerticalItem verticalItem = new VerticalItem(viewItems);
        return verticalItem;
    }
}
```

縦のリストを管理するAdapter

```java:VerticalRecyclerViewAdapter

public class VerticalRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private ArrayList<Object> mList;
    private static final int HORIZONTAL_VIEW_TYPE = 0;

    public void setList(ArrayList list) {
        mList = list;
    }

    @Override
    public int getItemCount() {
        if (mList != null) {
            return mList.size();
        }
        return 0;
    }

    @Override
    public int getItemViewType(int position) {
        Object item = mList.get(position);
        if (item instanceof VerticalItem) {
            return HORIZONTAL_VIEW_TYPE;
        }
        return super.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case HORIZONTAL_VIEW_TYPE:
                View itemView =
                        LayoutInflater.from(parent.getContext()).inflate(R.layout.horizontal_recycler_view, parent, false);
                return new HorizontalRecycleViewHolder(itemView);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (holder.getItemViewType()) {
            case HORIZONTAL_VIEW_TYPE:
                HorizontalRecycleViewHolder
                        horizontalRecycleViewHolder = (HorizontalRecycleViewHolder) holder;
                // 横に並ぶアイテムをセット
                VerticalItem verticalItem = (VerticalItem) mList.get(position);
                horizontalRecycleViewHolder.bindViewHolder(verticalItem);
                break;
        }
    }
}
```

２、
この中で出て来るHorizontalRecycleViewHolderで、新たにRecyclerViewとAdapterを用意する
（onCreateViewHolderのViewHolderをreturnする段階で、RecyclerViewとAdapterを生成）

３、
要素をバインドする時に呼ばれる横用のリストをそのAdapterにセットする
（onBindViewHolderで呼ばれるbindViewHolderでリストをセット）

```java:HorizontalRecycleViewHolder
public class HorizontalRecycleViewHolder extends RecyclerView.ViewHolder {

    private RecyclerView mHorizontalRecyclerView;
    private HorizontalRecyclerViewAdapter mHorizontalRecyclerViewAdapter;

    public HorizontalRecycleViewHolder(View itemView) {
        super(itemView);

        // RecyclerView
        mHorizontalRecyclerView = itemView.findViewById(R.id.horizontal_recycler_view);

        // LayoutManager(Horizontal)
        LinearLayoutManager linearLayoutManager =
                new LinearLayoutManager(itemView.getContext(), LinearLayoutManager.HORIZONTAL, false);
        mHorizontalRecyclerView.setLayoutManager(linearLayoutManager);

        // Adapter
        mHorizontalRecyclerViewAdapter = new HorizontalRecyclerViewAdapter();
        mHorizontalRecyclerView.setAdapter(mHorizontalRecyclerViewAdapter);
    }

    public void bindViewHolder(VerticalItem verticalItem) {
        // データをセット
        mHorizontalRecyclerViewAdapter.setList(verticalItem.getList());
        mHorizontalRecyclerViewAdapter.notifyDataSetChanged();
    }
}
```

横のリストを管理するAdapter
(HorizontalRecycleViewHolder内でインスタンス化するAdapter)

```java:HorizontalRecyclerViewAdapter
public class HorizontalRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private ArrayList<Object> mList;
    private static final int VIEW_ITEM_TYPE = 0;

    public void setList(ArrayList list) {
        mList = list;
    }

    @Override
    public int getItemCount() {
        if (mList != null) {
            return mList.size();
        }
        return 0;
    }

    @Override
    public int getItemViewType(int position) {
        Object item = mList.get(position);
        if (item instanceof VerticalItem) {
            return VIEW_ITEM_TYPE;
        }
        return super.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case VIEW_ITEM_TYPE:
                View itemView =
                        LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false);
                return new ViewItemHolder(itemView);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (holder.getItemViewType()) {
            case VIEW_ITEM_TYPE:
                ViewItemHolder viewItemHolder = (ViewItemHolder) holder;
                ViewItem viewItem = (ViewItem) mList.get(position);
                viewItemHolder.bindViewHolder(viewItem);
                break;
        }
    }
}
```

こうすることで中にRecyclerViewの中にRecyclerViewが設置できました!
GooglePlay的なデザインのアプリを作って見たくなりますね

二日目は、@taptappunさんの
https://qiita.com/taptappun/items/7fae4317d751245b2089
です。（修正）

今年もAdventCalendarで勉強させていただきます:laughing: