LoginSignup
27

More than 5 years have passed since last update.

RecyclerView(縦) in RecyclerView(横)

Last updated at Posted at 2017-12-01

AdventCalendar Android その2 の一日目の記事です!

RecyclerView in RecyclerViewでどんなことができる?

こんなことができる

方法

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

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

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

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

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

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)

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:

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
27