DataTable class
Material 2 설계 사양을 따르는 데이터 테이블입니다.
열 크기는 표의 내용에 따라 자동으로 조정됩니다. 이 위젯을 사용하여 많은 양의 데이터를 표시하려면 각 열의 크기를 조정하기 위해 한 번, 그리고 표의 레이아웃을 조정할 때 한 번, 총 두 번 측정해야 하므로 비용이 많이 듭니다.
공식 문서 코드
이러한 상황이 생길 수 있다. 보여주고 싶은 중요한 데이터가 있고 그 데이터를 표로 정리해서 보여주고 싶을 때. 이럴 때에는 어떤 위젯을 사용해야 할까? 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 에 대해서 알아보았다. 사용하기 굉장히 편하니 꼭 사용해 보길 바라고 도움이 되었길 바라며 마치겠다.