Skip to content

The Sectioned Recycler View Adapter

The sectioned recycler view adapter is an 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.

Using the Sectioned Recycler View Adapter

The sectioned recycler view adapter can be used with a standard RecyclerView.

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

Create your Sectioned Recycler View Adapter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    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);

1

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 a enum class named FormCell.WidgetType. You can use the SDK provided enum WidgetType as return type in getViewType method call. For example, below is an sample implementation of getItemViewType(int section, int row).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
            @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 secttion 0
                        return FormCell.WidgetType.ATTACHMENT.ordinal();
                    case 1:
                        // create an NoteFormCell for all positions in secttion 1
                        return FormCell.WidgetType.NOTE.ordinal();
                    case 2:
                        // create an DurationPickerFormCell for all positions in secttion 2
                        return FormCell.WidgetType.DURATION_PICKER.ordinal();
                    case 3:
                        // create an SliderFormCell for all positions in secttion 3
                        return FormCell.WidgetType.SLIDER.ordinal();
                    case 4:
                        // create an DateTimePickerFormCell for all positions in secttion 4
                        return FormCell.WidgetType.DATE_TIME_PICKER.ordinal();                   
                    default:
                        // create an 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 views. Make sure your View implements the FormCell 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.

    1
    2
    3
    4
    5
    6
    7
    interface FormCellCreator {
        @NonNull
        /*
            Given an integer create a specific FormCell type
         */
        View createCell(int type);
    }
    
    Create a FormCellCreator which creates/inflates your custom FormCell.
    1
    2
    3
    4
    5
    6
    7
            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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
```java
    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 pre-defined FormCell.WidgetType constants.

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

```java
            @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 secttion 0
                        return FormCell.WidgetType.ATTACHMENT.ordinal();
                    case 1:
                        // create an NoteFormCell for all positions in secttion 1
                        return FormCell.WidgetType.NOTE.ordinal();
                    case 2:
                        // create an DurationPickerFormCell for all positions in secttion 2
                        return FormCell.WidgetType.DURATION_PICKER.ordinal();
                    case 3:
                        // create an SliderFormCell for all positions in secttion 3
                        return FormCell.WidgetType.SLIDER.ordinal();
                    case 4:
                        // create an DateTimePickerFormCell for all positions in secttion 4
                        return FormCell.WidgetType.DATE_TIME_PICKER.ordinal();                   
                    default:
                        // create an NoteFormCell for all positions by default
                        return CUSTOM_FORM_CELL;
                }
            }

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

```