Horizontal Scrollable Table in Flutter

Published September 18, 2020

In this post we are going to create a School student Attendance Page. we know students details will contains like Student Name, Roll Number, Presetn/Absent status, Time.

How we will show these many details in single row with fixed sizes. 

 

Horizontal Table Flutter

 

To show these details in this post we are going to use HorizontalDataTable plugin.

 

constructor

const HorizontalDataTable({
  @required this.leftHandSideColumnWidth,
  @required this.rightHandSideColumnWidth,
  this.isFixedHeader = false,
  this.headerWidgets,
  this.leftSideItemBuilder,
  this.rightSideItemBuilder,
  this.itemCount = 0,
  this.leftSideChildren,
  this.rightSideChildren,
  this.rowSeparatorWidget = const Divider(
    color: Colors.transparent,
    height: 0.0,
    thickness: 0.0,
  ),
  this.elevation = 3.0,
  this.elevationColor = Colors.black54,
  this.leftHandSideColBackgroundColor = Colors.white,
  this.rightHandSideColBackgroundColor = Colors.white,
})

 

Let's get started.

Step 1: Create an flutter application

Step 2: Add dependencies in pubspec.yaml file

dependencies:
  flutter:
    sdk: flutter
  horizontal_data_table: ^1.0.6+2

 

Step 3: Add below code

import 'package:horizontal_data_table/horizontal_data_table.dart';
import 'package:flutter/material.dart';
class HorizontalTable extends StatefulWidget {



  @override
  _HorizontalTableState createState() => _HorizontalTableState();
}

class _HorizontalTableState extends State<HorizontalTable> {
  static const int sortName = 0;
  static const int sortStatus = 1;
  bool isAscending = true;
  int sortType = sortName;

  @override
  void initState() {
    user.initData(100);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.green,
        title: Text("Horizontal Table"),
      ),
      body: _getBodyWidget(),
    );
  }

  Widget _getBodyWidget() {
    return Container(
      child: HorizontalDataTable(
        leftHandSideColumnWidth: 120,
        rightHandSideColumnWidth: 600,
        isFixedHeader: true,
        headerWidgets: _getTitleWidget(),
        leftSideItemBuilder: _generateFirstColumnRow,
        rightSideItemBuilder: _generateRightHandSideColumnRow,
        itemCount: user.userInfo.length,
        rowSeparatorWidget: const Divider(
          color: Colors.black54,
          height: 1.0,
          thickness: 0.0,
        ),
        leftHandSideColBackgroundColor: Color(0xFFFFFFFF),
        rightHandSideColBackgroundColor: Color(0xFFFFFFFF),
      ),
      height: MediaQuery
          .of(context)
          .size
          .height,
    );
  }

  List<Widget> _getTitleWidget() {
    return [
      FlatButton(

        padding: EdgeInsets.all(0),
        child: _getTitleItemWidget(
            'Student' + (sortType == sortName ? (isAscending ? '  ↓' : '  ↑') : ''),
            120,Colors.pink),
        onPressed: () {
          sortType = sortName;
          isAscending = !isAscending;
          user.sortName(isAscending);
          setState(() {

          });
        },
      ),
      Container(width: 2,height: 56,color: Colors.white,),
      _getTitleItemWidget('Rool No', 100,Colors.red),
      Container(width: 2,height: 56,color: Colors.white,),
      FlatButton(
        padding: EdgeInsets.all(0),
        child: _getTitleItemWidget('Attendance' +
            (sortType == sortStatus ? (isAscending ? '↓' : '↑') : ''), 100,Colors.red),
        onPressed: () {
          sortType = sortStatus;
          isAscending = !isAscending;
          user.sortStatus(isAscending);
          setState(() {

          });
        },
      ),
      Container(width: 2,height: 56,color: Colors.white,),
      _getTitleItemWidget('Start Time', 100,Colors.red),
      Container(width: 2,height: 56,color: Colors.white,),
      _getTitleItemWidget('End Time', 200,Colors.red),
    ];
  }

  Widget _getTitleItemWidget(String label, double width,color) {
    return Container(
      color: color,
      child: Text(label, style: TextStyle(fontWeight: FontWeight.bold,fontSize: 18,color: Colors.white)),
      width: width,
      height: 56,
      padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
      alignment: Alignment.centerLeft,
    );
  }

  Widget _generateFirstColumnRow(BuildContext context, int index) {
    return Container(
      color: Colors.blueGrey,
      child: Text(user.userInfo[index].name,style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold,color: Colors.white),),
      width: 120,
      height: 52,
      padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
      alignment: Alignment.centerLeft,
    );
  }

  Widget _generateRightHandSideColumnRow(BuildContext context, int index) {
    return Row(
      children: <Widget>[
        Container(
          child: Text(user.userInfo[index].roll_no,style: TextStyle(fontSize: 18),),
          width: 100,
          height: 52,
          padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
          alignment: Alignment.centerLeft,
        ),
        Container(width: 2,height: 56,color: Colors.blueGrey,),
        Container(
          child: Row(
            children: <Widget>[
              Icon(
                  user.userInfo[index].status
                      ? Icons.clear
                      : Icons.check,
                  color: user.userInfo[index].status ? Colors.red : Colors
                      .green),
              Text(user.userInfo[index].status ? 'absent' : 'present',style: TextStyle(fontSize: 18),)
            ],
          ),
          width: 100,
          height: 52,
          padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
          alignment: Alignment.centerLeft,
        ),
        Container(width: 2,height: 56,color: Colors.blueGrey,),
        Container(
          child: Text(user.userInfo[index].start_time,style: TextStyle(fontSize: 18),),
          width: 100,
          height: 52,
          padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
          alignment: Alignment.centerLeft,
        ),
        Container(width: 2,height: 56,color: Colors.blueGrey,),
        Container(
          child: Text(user.userInfo[index].end_time,style: TextStyle(fontSize: 18),),
          width: 200,
          height: 52,
          padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
          alignment: Alignment.centerLeft,
        ),
      ],
    );
  }
}

Student user = Student();

class Student {
  List<StudentInfo> _userInfo = List<StudentInfo>();

  void initData(int size) {
    for (int i = 0; i < size; i++) {
      _userInfo.add(StudentInfo(
          "Student_$i", i % 3 == 0, 'St_No $i', '10:00 AM', '12:30 PM'));
    }
  }

  List<StudentInfo> get userInfo => _userInfo;

  set userInfo(List<StudentInfo> value) {
    _userInfo = value;
  }

  ///
  /// Single sort, sort Name's id
  void sortName(bool isAscending) {
    _userInfo.sort((a, b) {
      int aId = int.tryParse(a.name.replaceFirst('Student_', ''));
      int bId = int.tryParse(b.name.replaceFirst('Student_', ''));
      return (aId - bId) * (isAscending ? 1 : -1);
    });
  }

  ///
  /// sort with Status and Name as the 2nd Sort
  void sortStatus(bool isAscending) {
    _userInfo.sort((a, b) {
      if (a.status == b.status) {
        int aId = int.tryParse(a.name.replaceFirst('User_', ''));
        int bId = int.tryParse(b.name.replaceFirst('User_', ''));
        return (aId - bId);
      } else if (a.status) {
        return isAscending ? 1 : -1;
      } else {
        return isAscending ? -1 : 1;
      }
    });
  }
}

class StudentInfo {
  String name;
  bool status;
  String roll_no;
  String start_time;
  String end_time;

  StudentInfo(this.name, this.status, this.roll_no, this.start_time,
      this.end_time);
}

 

 

Step 4: Update main.dart file

void main() {
  runApp( MaterialApp(
    home: HorizontalTable(),
  ));
}

 

 

Step 5: Run Application

 

 

Tags: Table, Horizontable Table

 

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

6171 Views