The ArkUI development framework provides the grid component in NDK APIs since API version 12. The grid allows you to divide a page into cells by rows and columns, and specify the cell where a child component is located and the number of rows and columns it occupies, thereby achieving different layout requirements. For example, you can create widgets and application icons of different sizes, and group images by date for display.
After creating a grid, you can set the number of rows and columns occupied by child components. In the scrolling scenario, you can also handle scroll events.
For details about the basic usage of the NDK and how to use the NDK APIs to build UIs, see Integrating with ArkTS Pages.
You can call createNode(ARKUI_NODE_GRID) through ArkUI_NativeNodeAPI_1 to obtain the component object pointer, and set attributes such as NODE_GRID_COLUMN_TEMPLATE, NODE_GRID_ROW_TEMPLATE, NODE_GRID_COLUMN_GAP, and NODE_GRID_ROW_GAP in ArkUI_NodeAttributeType to create a grid.
Encapsulate the common attributes of the grid component into a custom ArkUIGridNode class by referring to the implementation of the list component in Example.
#ifndef MYAPPLICATION_ARKUIGRIDNODE_H
#define MYAPPLICATION_ARKUIGRIDNODE_H
#include "ArkUINode.h"
#include "ArkUINodeAdapter.h"
namespace NativeModule {
class ArkUIGridNode : public ArkUINode {
public:
ArkUIGridNode() : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_GRID))
{
}
~ArkUIGridNode() override {}
void SetColumnsTemplate(const std::string &str)
{
ArkUI_AttributeItem item = {.string = str.c_str()};
nativeModule_->setAttribute(handle_, NODE_GRID_COLUMN_TEMPLATE, &item);
}
void SetRowsTemplate(const std::string &str)
{
ArkUI_AttributeItem item = {.string = str.c_str()};
nativeModule_->setAttribute(handle_, NODE_GRID_ROW_TEMPLATE, &item);
}
void SetColumnsGap(float val)
{
ArkUI_NumberValue value[] = {{.f32 = val}};
ArkUI_AttributeItem item = {value, 1};
nativeModule_->setAttribute(handle_, NODE_GRID_COLUMN_GAP, &item);
}
void SetRowsGap(float val)
{
ArkUI_NumberValue value[] = {{.f32 = val}};
ArkUI_AttributeItem item = {value, 1};
nativeModule_->setAttribute(handle_, NODE_GRID_ROW_GAP, &item);
}
void SetLayoutOptions(ArkUI_GridLayoutOptions *option)
{
if (option == nullptr) {
return;
}
ArkUI_AttributeItem item = {.object = option};
nativeModule_->setAttribute(handle_, NODE_GRID_LAYOUT_OPTIONS, &item);
}
void SetScrollBar(int32_t barState)
{
ArkUI_NumberValue value[] = {{.i32 = barState}};
ArkUI_AttributeItem item = {value, 1};
nativeModule_->setAttribute(handle_, NODE_SCROLL_BAR_DISPLAY_MODE, &item);
}
void SetLazyAdapter(const std::shared_ptr<ArkUINodeAdapter> &adapter)
{
if (!IsNotNull(adapter)) {
return;
}
ArkUI_AttributeItem item{nullptr, 0, nullptr, adapter->GetAdapter()};
nativeModule_->setAttribute(handle_, NODE_GRID_NODE_ADAPTER, &item);
_adapter = adapter;
}
void ReleaseAdapter() { return _adapter.reset(); }
private:
std::shared_ptr<ArkUINodeAdapter> _adapter;
};
} // namespace NativeModule
#endif // MYAPPLICATION_ARKUIGRIDNODE_H The code for creating a grid component with six rows and four columns and setting row and column spacing using ArkUIGridNode is as follows:
auto grid = std::make_shared<ArkUIGridNode>();
grid->SetPercentWidth(0.9f);
grid->SetHeight(SIX_ROWS * ITEM_HEIGHT + (SIX_ROWS - 1) * ROWS_GAP);
grid->SetColumnsTemplate("1fr 1fr 1fr 1fr");
grid->SetRowsTemplate("1fr 1fr 1fr 1fr 1fr 1fr");
grid->SetColumnsGap(10.0f);
grid->SetRowsGap(ROWS_GAP); NODE_GRID_COLUMN_TEMPLATE and NODE_GRID_ROW_TEMPLATE support multiple modes of defining the number of columns and rows. The following uses the number of columns as an example:
// Use the fr unit (fraction, proportion).
grid->SetColumnsTemplate("1fr 2fr 1fr"); // The width of the second column is twice that of the first and third columns.
// Use the repeat function.
grid->SetColumnsTemplate("repeat(auto-fill, 100vp)"); // Automatically fill columns with a width of 100 vp. For more information, see columnsTemplate.
By default, all child components of the grid component occupy one row and one column. For such scenarios, this can also be achieved by setting NODE_LIST_LANES in ArkUI_NodeAttributeType through the list component. The grid layout is more suitable for scenarios where some child components occupy multiple rows or columns, such as widgets and icons of different sizes on a page, or grouping images by date for display. Since API version 22, you can create a grid and pass a proper ArkUI_GridLayoutOptions to implement this scenario.
| Requirement Scenario | Recommended Solution | Description |
|---|---|---|
| Fixed-row-and-column grid, with some items occupying multiple rows and columns | OH_ArkUI_GridLayoutOptions_RegisterGetRectByIndexCallback | Flexibly controls the position and size of each item. |
| Scrollable grid, with a group title occupying the entire row | OH_ArkUI_GridLayoutOptions_SetIrregularIndexes | Specifies the index that occupies the entire row. |
As shown in the following figure, some child components are placed in the previously created grid layout of 6 rows and 4 columns. 0 occupies two rows and four columns, 1 occupies two rows and two columns, and 2 occupies one row and two columns. There is an empty row between 0 and 1, simulating the scenario where widgets and icons of different sizes are placed on the page.

You can use OH_ArkUI_GridLayoutOptions_RegisterGetRectByIndexCallback to set a callback for the Grid component to obtain the position of each child component. In the callback, you can specify the start row number, start column number, number of occupied rows, and number of occupied columns of each child component, that is, ArkUI_GridItemRect. The layout in the preceding figure can be implemented using the following code:
"0" occupies two rows and four columns starting from the upper left corner of the grid. Therefore, set ArkUI_GridItemRect to {0, 0, 2, 4}. The position and size settings for other child components follow the same logic.
auto option = std::make_shared<ArkuiGridLayoutOptions>();
auto layoutOptions = option->GetLayoutOptions();
OH_ArkUI_GridLayoutOptions_RegisterGetRectByIndexCallback(
option->GetLayoutOptions(), nullptr, [](int32_t itemIndex, void *userData) -> ArkUI_GridItemRect {
switch (itemIndex) {
case 0:
return ArkUI_GridItemRect{0, 0, 2, 4};
case 1:
return ArkUI_GridItemRect{3, 0, 2, 2};
case ITEM_INDEX_2:
return ArkUI_GridItemRect{3, 2, 1, 2};
case ITEM_INDEX_3:
return ArkUI_GridItemRect{4, 2, 1, 1};
case ITEM_INDEX_4:
return ArkUI_GridItemRect{4, 3, 1, 1};
case ITEM_INDEX_5:
return ArkUI_GridItemRect{5, 0, 1, 1};
case ITEM_INDEX_6:
return ArkUI_GridItemRect{5, 1, 1, 1};
case ITEM_INDEX_7:
return ArkUI_GridItemRect{5, 2, 1, 1};
default:
return ArkUI_GridItemRect{5, 3, 1, 1};
}
});
grid->SetLayoutOptions(layoutOptions); The following figure simulates the scenario where images or files are displayed in groups, where the child component serving as the group name occupies an entire row, and other child components occupy 1 row and 1 column.

For a vertically scrolling grid layout, you only need to set the number of columns, and do not need to set the number of rows.
grid->SetColumnsTemplate("1fr 1fr 1fr");
grid->SetColumnsGap(10.0f);
grid->SetRowsGap(10.0f);
grid->SetScrollBar(ARKUI_SCROLL_BAR_DISPLAY_MODE_OFF); To display data in groups, you can use OH_ArkUI_GridLayoutOptions_SetIrregularIndexes to set the indexes corresponding to the group nodes. The child components corresponding to these indexes will occupy an entire row, while other child components will occupy 1 row and 1 column.
auto layoutOptions = std::make_shared<ArkuiGridLayoutOptions>();
uint32_t irregularIndexes[] = {0, 6, 8, 15};
OH_ArkUI_GridLayoutOptions_SetIrregularIndexes(layoutOptions->GetLayoutOptions(), irregularIndexes,
sizeof(irregularIndexes) / sizeof(irregularIndexes[0]));
grid->SetLayoutOptions(layoutOptions->GetLayoutOptions()); The Grid component supports the use of NodeAdapter to generate child components on demand to improve performance. For details, see NodeAdapter Overview and Displaying Data by Group.
Refer to the sample code for listening to the NODE_LIST_ON_SCROLL_INDEX event in the ArkUI_NodeEventType component in Adding an Event Listener to implement grid scroll event listening.
The Grid component supports the following scroll events:
| Event Enum | Event Description | Start API Version |
|---|---|---|
| NODE_SCROLL_EVENT_ON_SCROLL_FRAME_BEGIN | Called back when the grid component starts scrolling each frame, with the offset to be scrolled in the current frame and the current scrolling state. | 12 |
| NODE_SCROLL_EVENT_ON_SCROLL_START | Triggered when the Grid component starts scrolling. | 22 |
| NODE_SCROLL_EVENT_ON_SCROLL_STOP | Triggered when the Grid component stops scrolling. | 22 |
| NODE_SCROLL_EVENT_ON_REACH_START | Triggered when the Grid component reaches the start position. | 12 |
| NODE_SCROLL_EVENT_ON_REACH_END | Triggered when the Grid component reaches the end position. | 12 |
| NODE_SCROLL_EVENT_ON_WILL_STOP_DRAGGING | Triggered when the user is about to release the drag on the Grid component. | 20 |
| NODE_SCROLL_EVENT_ON_WILL_START_DRAGGING | Called back when the grid component is about to start dragging. | 21 |
| NODE_SCROLL_EVENT_ON_DID_STOP_DRAGGING | Triggered when the drag on the Grid component ends. | 21 |
| NODE_SCROLL_EVENT_ON_WILL_START_FLING | Triggered when the sliding animation of the Grid component is about to start. | 21 |
| NODE_SCROLL_EVENT_ON_DID_STOP_FLING | Triggered when the sliding animation of the Grid component ends. | 21 |
| NODE_GRID_ON_SCROLL_INDEX | Triggered when a child component slides into or out of the display area of the Grid component. The callback returns the index values of the child components at the start and end positions of the display area. | 22 |
| NODE_GRID_ON_WILL_SCROLL | Triggered before the Grid component slides. The callback returns the offset amount by which the component is to slide in the current frame, current sliding state, and source of the sliding operation. | 22 |
| NODE_GRID_ON_DID_SCROLL | Triggered after the Grid component slides. The callback returns the offset amount by which the component has scrolled and the current scroll state. | 22 |
| NODE_GRID_ON_SCROLL_BAR_UPDATE | Sets the position and length of the scrollbar at the end of each frame layout. | 22 |
You can set NODE_SCROLL_OFFSET and NODE_GRID_SCROLL_TO_INDEX in ArkUI_NodeAttributeType to control the list scroll position.
Since API version 23, NODE_GRID_SCROLL_TO_INDEX is supported.