Skip to content

Sectioned Recycler View Adapter

The SectionedRecyclerViewAdapter is a special RecyclerView.Adapter which enables you to manage a list of form cells into multiple sections, put headers and footers on the sections, and put section separators between two sections. It is a subtype of RecyclerView.Adapter and can be used with RecyclerView.

The SectionedRecyclerViewAdapter can be used with a standard RecyclerView.

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

Create Your SectionedRecyclerViewAdapter

    SectionedRecyclerViewAdapter adapter = new SectionedRecyclerViewAdapter() {

            @Override
            public int getNumberOfSections() {
                    // How many sections?
                    return number of sections;
            }

            @Override
            public int getItemCountForSection(int section) {
                    // How many items in given section?
                    return number of items in given section
            }


            @Override
            public int getItemViewType(int section, int row) {
                // Get type of view at given section and item position in given section.
                // You can use different `WidgetTypes` (discussed later in this documentation) provided by SDK
                return WidgetType.SLIDER.ordinal(); // SliderFormCell type
            }


            @Override
            public void onBindCellHolder(@NonNull FormCellHolder cellHolder, int section, int row) {
                // Bind the given view, section number and position within the section
            }

            @Override
            protected void onBindHeader(@NonNull FormCellHolder header, int section) {
                // Bind the header of the section
            }

            @Override
            protected void onBindFooter(@NonNull FormCellHolder footer, int section) {
                // Bind the footer of the section
            }

        };

    RecyclerView recycler = findViewById(R.id.sectionedRecyclerView);
    recycler.setAdapter(adapter);

Section Recycler View

Enabling and Disabling Footers, Headers, and Separators

The list picker form cell allows you to enable or disable the headers, footers and separators as per your requirements.

  • setFooterEnabled(boolean): Enabled/Disable the footer for sections
  • setHeaderEnabled(boolean): Enabled/Disable the header for sections
  • setSeparatorEnabled(boolean): Enabled/Disable the separator for sections

WidgetTypes

To save you the trouble of creating different form cells in onCreateView(int viewType), the SDK inflates these form cells automatically based on int value returned from getItemViewType(int section, int row) method. To enable this automatic creation of form cells, SectionedRecyclerViewAdapter has to be aware of which integer maps to which form cell.

For example, FormCell.Widget.Note.ordinal is mapped to NoteFormCell and FormCell.Widget.SWITCH.ordinal is mapped to SwitchFormCell.

These standard (registered by default) integers are provided as an enumeration class named FormCell.WidgetType. You can use the SDK provided enumeration WidgetType as return type in getViewType method call. For example, below is a sample implementation of getItemViewType(int section, int row).

            @Override
            public int getItemViewType(int section, int pos) {
                // for simplicity all the items in a section are of one type. So ignoring pos
                switch (section) {
                    case 0:
                        // create an AttachmentFormCell for all positions in section 0
                        return FormCell.WidgetType.ATTACHMENT.ordinal();
                    case 1:
                        // create a `NoteFormCell` for all positions in section 1
                        return FormCell.WidgetType.NOTE.ordinal();
                    case 2:
                        // create a DurationPickerFormCell for all positions in section 2
                        return FormCell.WidgetType.DURATION_PICKER.ordinal();
                    case 3:
                        // create a SliderFormCell for all positions in section 3
                        return FormCell.WidgetType.SLIDER.ordinal();
                    case 4:
                        // create a `DateTimePickerFormCell` for all positions in section 4
                        return FormCell.WidgetType.DATE_TIME_PICKER.ordinal();
                    default:
                        // create a `NoteFormCell` for all positions by default
                        return FormCell.WidgetType.NOTE.ordinal();
                }
            }

            /*
                If you use the Widget Type constants which are registered with `SectionedRecyclerViewAdapter` then you do not have to
                create the views specifically.  `SectionedRecyclerViewAdapter` can create the views for you.
            */
            @NonNull
            @Override
            public FormCellHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                super.onCreateViewHolder(parent, vireType);
            }

The following are available WidgetTypes constants:

WidgetType Description
SWITCH SwitchFormCell
FILTER FilterFormCell
SLIDER SliderFormCell
Separator Separator
LISTPICKER ListPickerFormCell
ATTACHMENT AttachmentFormCell
DATE_TIME_PICKER DateTimePickerFormCell
NOTE NoteFormCell
DURATION_PICKER DurationPickerFormCell
BUTTON ButtonFormCell
SIMPLE_CELL SimplePropertyFormCell
CHOICE_CONTROL ChoiceFormCell
EXTENSION_CELL User defined form cell
SECTION_HEADER_FOOTER Sectioned Header Footer

Using CustomFormCell

You can also create custom form cells and use them within the SectionedRecyclerViewAdapter. In order to facilitate this, SectionedRecyclerViewAdapter has to be informed of what integer maps to the custom form cell and how to create the custom form cell.

The following steps show how to use your custom form cell with SectionedRecyclerViewAdapter:

  • SectionedRecyclerViewAdapter only accepts FormCell<T> views. Make sure your View implements the FormCell<T> interface.
  • You need to inform SectionedRecyclerViewAdapter about how to create the custom form cell. SectionedRecyclerViewAdapter depends on FormCellCreator to create the form cells. A FormCellCreator object is a functional interface to create the FormCell views when required.

    interface FormCellCreator {
        @NonNull
        /*
            Given an integer create a specific FormCell type
         */
        View createCell(int type);
    }
    

    Create a FormCellCreator which creates/inflates your custom FormCell.

            FormCellCreator customCellCreator = new FormCellCreator() {
                @NonNull
                @Override
                public View onCreateCell(@NonNull ViewGroup parent) {
                    return new CustomFormCell1(parent.getContext());
                }
            }
    
  • Register FormCellCreator to SectionedRecyclerViewAdapter

    You can register your FormCellCreator with an integer (which you will return as viewType from getItemViewType(int section, int row)) using registerCellCreator(int, FormCellCreator) API.

        int CUSTOM_FORM_CELL = 500;
        adapter.registerCellCreator(CUSTOM_FORM_CELL, customCellCreator);
    

    Note that the value of CUSTOM_FORM_CELL should be 1001 or higher, in order not to collide with the ordinal values of the predefined FormCell.WidgetType constants.

    With this done you can update your getItemViewType(int section, int row) as

    @Override
    public int getItemViewType(int section, int pos) {
        // for simplicity, all the items in a section are of one type. So ignoring pos
        switch (section) {
            case 0:
                // create an AttachmentFormCell for all positions in section 0
                return FormCell.WidgetType.ATTACHMENT.ordinal();
            case 1:
                // create a `NoteFormCell` for all positions in section 1
                return FormCell.WidgetType.NOTE.ordinal();
            case 2:
                // create a DurationPickerFormCell for all positions in section 2
                return FormCell.WidgetType.DURATION_PICKER.ordinal();
            case 3:
                // create a SliderFormCell for all positions in section 3
                return FormCell.WidgetType.SLIDER.ordinal();
            case 4:
                // create a `DateTimePickerFormCell` for all positions in section 4
                return FormCell.WidgetType.DATE_TIME_PICKER.ordinal();
            default:
                // create a `NoteFormCell` for all positions by default
            return CUSTOM_FORM_CELL;
        }
    }
    
    /*
        If you use the Widget Type constants that are registered with `SectionedRecyclerViewAdapter`, then you do not have to
        create the views specifically.  `SectionedRecyclerViewAdapter` can create the views for you.
    */
    @NonNull
    @Override
    public FormCellHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        super.onCreateViewHolder(parent, viewType);
    }
    

Last update: August 12, 2020