본문 바로가기
flutter/Widget of the Week

Flutter[플러터] / DataTable 을 사용하여 정렬 기능 있는 표 만들기 (데이터, 테이블, Colums, Rows, sort) DataTable (Flutter Widget of the Week)

by ch5c 2025. 6. 13.
반응형

DataTable class

Material 2 설계 사양을 따르는 데이터 테이블입니다.

열 크기는 표의 내용에 따라 자동으로 조정됩니다. 이 위젯을 사용하여 많은 양의 데이터를 표시하려면 각 열의 크기를 조정하기 위해 한 번, 그리고 표의 레이아웃을 조정할 때 한 번, 총 두 번 측정해야 하므로 비용이 많이 듭니다.

https://youtu.be/ktTajqbhIcY

공식 문서 코드

 

 


이러한 상황이 생길 수 있다. 보여주고 싶은 중요한 데이터가 있고 그 데이터를 표로 정리해서 보여주고 싶을 때. 이럴 때에는 어떤 위젯을 사용해야 할까? Table 위젯? 물론 훌륭한 선택이다. 다만 더 쉽고 마테리얼 디자인을 따르는 좋은 위젯이 있는데 바로 DataTable 이다.

이 DataTable 은 행(Row)과 열(Column)로 구성되어 있는데 셀에 있는 내용에 따라 열의 크기를 자동으로 지정해 표를 만들어주는 위젯이 되겠다. 바로 한번 알아보자.

하위 속성
속성명 타입 기본값 설명
columns List<DataColumn> 테이블의 열 구성을 정의하는 DataColumn 목록
sortColumnIndex int? null 정렬 기준이 되는 열의 인덱스
sortAscending bool true 정렬이 오름차순인지 여부
onSelectAll ValueSetter<bool?>? null 헤더의 전체 선택 체크박스 변경 시 호출되는 콜백
decoration Decoration? null 테이블의 배경 및 테두리 데코레이션
dataRowColor MaterialStateProperty<Color?>? null 데이터 행의 배경색
dataRowMinHeight double? null 데이터 행의 최소 높이
dataRowMaxHeight double? null 데이터 행의 최대 높이
dataTextStyle TextStyle? null 데이터 행에 사용되는 텍스트 스타일
headingRowColor MaterialStateProperty<Color?>? null 헤더 행의 배경색
headingRowHeight double? null 헤더 행의 높이
headingTextStyle TextStyle? null 헤더 행에 사용되는 텍스트 스타일
horizontalMargin double? null 행의 가장자리와 콘텐츠 사이의 수평 마진
columnSpacing double? null 각 열 사이의 수평 간격
showCheckboxColumn bool true 선택 가능한 행에 체크박스 열을 표시할지 여부
rows List<DataRow> 테이블에 표시할 데이터 행 목록
dividerThickness double? null 행 사이의 구분선 두께
showBottomBorder bool false 테이블 하단에 테두리를 표시할지 여부
checkboxHorizontalMargin double? null 체크박스 주변의 수평 마진
border TableBorder? null 테이블 테두리 스타일
clipBehavior Clip Clip.none 테이블 컨텐츠의 클리핑 동작

 

이 위젯은 위의 속성표 같은 진짜 표를 만들어주는 위젯인데 굉장히 간단한 사용법을 가지고 있다. 먼저 열을 정의해 주고 다음으로 각 행과 그에 해당하는 셀을 지정해 주면 된다. 이러면 끝이다.

DataTable(
  columns: [
    DataColumn(label: Text('Name')),
    DataColumn(label: Text('Age')),
    DataColumn(label: Text('Role')),
  ],
  rows: [
    DataRow(
      cells: [
        DataCell(Text('Sarah')),
        DataCell(Text('19')),
        DataCell(Text('Student')),
      ],
    ),
    DataRow(
      cells: [
        DataCell(Text('Janine')),
        DataCell(Text('43')),
        DataCell(Text('Professor')),
      ],
    ),
    DataRow(
      cells: <DataCell>[
        DataCell(Text('William')),
        DataCell(Text('27')),
        DataCell(Text('Associate Professor')),
      ],
    ),
  ],
)

DataTable 은 필수 값으로 colums(열) 와 rows(행) 를 넘겨주는데 columns 는 List<DataColumn> 타입이기 때문에 DataColumns 를 이용하여 표의 헤더, 열 제목(?)을 만들어 줄 수 있다.

rows 는 또한 List<DataRow> 타입이라 DataRow 를 배치해 주면 되는데 그 DataRow 위젯 안에는 cells 라는 하위 속성이 있다. 이 cells 안에 리스트 안에 넣어줄 위젯들을 배치하면 되는데 이것으로 표는 완성되게 된다.

하지만 이 위젯은 이것으로 끝나는 것이 아닌 아래 코드처럼 작성하여 정렬 기능을 넣어 줄 수도 있다.

 

간단하게 정렬기능을 하는 동작을 만들었다.

bool ascending = true;

먼저 정렬을 제어해 줄 bool 값 하나를 만들어준다.

그런 후 이제 정렬이 뒤바뀌게 되면 rows 안에 들어 있는 값들이 바뀌는 것이기 때문에 따로 List<DataRows> 타입 변수로 빼서 선언해 놨다.

List<DataRow> _rows = [
  DataRow(
    cells: [
      DataCell(Text('Sarah')),
      DataCell(Text('19')),
      DataCell(Text('Student')),
    ],
  ),
  DataRow(
    cells: [
      DataCell(Text('Janine')),
      DataCell(Text('43')),
      DataCell(Text('Professor')),
    ],
  ),
  DataRow(
    cells: <DataCell>[
      DataCell(Text('William')),
      DataCell(Text('27')),
      DataCell(Text('Associate Professor')),
    ],
  ),
];

이렇게 하면 이 위젯들을 마음대로 주무는게 가능해지는 것인데 여기서 reversed 를 사용하여 값을 뒤바꿔주는 로직을 만들었다.

void sortName() {
  setState(() {
    _rows = _rows.reversed.toList();
    ascending = !ascending;
  });
}

이렇게 하고 sortName() 을 DataColumn 안에서 호출시키게 하면

DataColumn(
  label: InkWell(
    onTap: sortName,
    child: ascending ? Text('Name↓') : Text('Name↑'),
  ),
),

간단한 정렬 기능이 완성되는 것이다. 이 밖에도 수정, 편집하게 만들 수도 있지만 다루진 않겠다.

근데 여기서 주의해야 할 점은 만약 칼럼을 2개 만들었는데 로우는 3개를 만들었다? 그럼 반드시 오류가 날 거다. 이점 주의하도록 하자.

이제 부가적(?)인 것들을 알아볼 텐데 먼저 정렬이다.

DataColumn(
  numeric: true,

DataColum 의 하위 속성인 numeric 값을 사용하여 기본 왼쪽 정렬인 것을 오른쪽 정렬로 만들어 줄 수 있다.

DataRow 에서 셀이 미리 선택되어 있게도 만들 수 있다.

DataRow(
  selected: true,

또한 DataCell 안에서는 기본적으로 onTap 속성을 지원하기 때문에 터치가 가능하게 만들 수 있다.

DataCell(
  onTap: () => print('선택!'),

 

이렇게 DataTable 에 대해서 알아보았다. 사용하기 굉장히 편하니 꼭 사용해 보길 바라고 도움이 되었길 바라며 마치겠다.

 

반응형