I have a TabBar set up with 8 different pages. I want to add a differentdata table into each page.
Is there a way to insert a DataTable widget into a static const List<Widget>?
Whenever I attempt to add a widget into my _tabs list, it gets mad.
Sorry if this isn't very descriptive, but maybe I'm just constructing the list of widgets incorrectly?
Current screenshot:
Current code gist:
import 'package:flutter/material.dart';
import 'package:sliced_inventory/nav_bar.dart';
class ViewEditScreen extends StatelessWidget {
const ViewEditScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: const NavBar(),
appBar: AppBar(
title: const Text("View Edit"),
centerTitle: true,
),
body: DefaultTabController(
length: 8,
child: Scaffold(
appBar: AppBar(
actions: const <Widget>[],
title: const TabBar(
tabs: [
Tab(text: "Freezer"),
Tab(text: "Back Cooler\n& Dry Storage"),
Tab(text: "Kitchen\nCooler"),
Tab(text: "Salad Cooler"),
Tab(text: "Dry Storage"),
Tab(text: "Spices"),
Tab(text: "Paper\nProducts"),
Tab(text: "Chemicals\nand Cleaning"),
],
indicatorColor: Colors.white,
),
),
body: const TabBarView(
children: _tabs
),
),
));
}
static const List<Widget> _tabs = [
Center(child: Text('Content of Tab Two')),
Center(child: Text('Content of Tab Two')),
Center(child: Text('Content of Tab Three')),
Center(child: Text('Content of Tab Four')),
Center(child: Text('Content of Tab Five')),
Center(child: Text('Content of Tab Six')),
Center(child: Text('Content of Tab Seven')),
Center(child: Text('Content of Tab Eight')),
];
}
I ended up making classes for each of the different tabs. I think overall this will help to keep things more organized. Here's the code of the whole file if others are trying to do the same.
import 'package:flutter/material.dart';
import 'package:sliced_inventory/nav_bar.dart';
class ViewEditScreen extends StatelessWidget {
const ViewEditScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: const NavBar(),
appBar: AppBar(
title: const Text("View Edit"),
centerTitle: true,
),
body: DefaultTabController(
length: 8,
child: Scaffold(
appBar: AppBar(
actions: const <Widget>[],
title: const TabBar(
tabs: [
Tab(text: "Freezer"),
Tab(text: "Back Cooler\n& Dry Storage"),
Tab(text: "Kitchen\nCooler"),
Tab(text: "Salad Cooler"),
Tab(text: "Dry Storage"),
Tab(text: "Spices"),
Tab(text: "Paper\nProducts"),
Tab(text: "Chemicals\nand Cleaning"),
],
indicatorColor: Colors.white,
),
),
body: const TabBarView(children: [
FreezerTab(),
BackCoolerDryStorageTab(),
KitchenCoolerTab(),
SaladCoolerTab(),
DryStorageTab(),
SpicesTab(),
PaperProductsTab(),
ChemicalsCleaningTab(),
]),
),
));
}
}
class FreezerTab extends StatelessWidget {
const FreezerTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('FreezerC1')),
DataColumn(label: Text('FreezerC2')),
DataColumn(label: Text('FreezerC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
class BackCoolerDryStorageTab extends StatelessWidget {
const BackCoolerDryStorageTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('BackCoolerDryStorageC1')),
DataColumn(label: Text('BackCoolerDryStorageC2')),
DataColumn(label: Text('BackCoolerDryStorageC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
class KitchenCoolerTab extends StatelessWidget {
const KitchenCoolerTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('KitchenCoolerC1')),
DataColumn(label: Text('KitchenCoolerC2')),
DataColumn(label: Text('KitchenCoolerC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
class SaladCoolerTab extends StatelessWidget {
const SaladCoolerTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('SaladCoolerC1')),
DataColumn(label: Text('SaladCoolerC2')),
DataColumn(label: Text('SaladCoolerC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
class DryStorageTab extends StatelessWidget {
const DryStorageTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('DryStorageC1')),
DataColumn(label: Text('DryStorageC2')),
DataColumn(label: Text('DryStorageC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
class SpicesTab extends StatelessWidget {
const SpicesTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('SpicesC1')),
DataColumn(label: Text('SpicesC2')),
DataColumn(label: Text('SpicesC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
class PaperProductsTab extends StatelessWidget {
const PaperProductsTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('PaperProductsC1')),
DataColumn(label: Text('PaperProductsC2')),
DataColumn(label: Text('PaperProductsC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
class ChemicalsCleaningTab extends StatelessWidget {
const ChemicalsCleaningTab({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(columns: const [
DataColumn(label: Text('ChemicalsCleaningC1')),
DataColumn(label: Text('ChemicalsCleaningC2')),
DataColumn(label: Text('ChemicalsCleaningC3')),
], rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('R1C1')),
DataCell(Text('R1C2')),
DataCell(Text('R1C3')),
],
),
]);
}
}
Related
I am trying to build an Android app in my college project but in faculty info, I am getting an error, like A RenderFlex overflowed by 7.5 pixels on the right.
import 'package:flutter/material.dart';
class Faculty extends StatefulWidget {
const Faculty({Key? key}) : super(key: key);
#override
_FacultyState createState() => _FacultyState();
}
class _FacultyState extends State<Faculty> {
final style = const TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Faculty Info'),
backgroundColor: const Color(0xff01A0C7),
),
body: ListView(
children: <Widget>[
const SizedBox(height: 35),
const Center(
child: Text(
'Faculty-Chart',
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
),
DataTable(
columns: const [
DataColumn(
label: Text(
'ID',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Name',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Contact no',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
],
rows: const [
DataRow(
cells: [
DataCell(Text('1')),
DataCell(Text('Amit Thakkar')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('2')),
DataCell(Text('Hemang Thakkar')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('3')),
DataCell(Text('Shrushti Gajjar')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('4')),
DataCell(Text('Dhruvi Thrivedi')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('5')),
DataCell(Text('Deep Kotharia')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('6')),
DataCell(Text('Vaibhai Patel')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('7')),
DataCell(Text('Jaina Patel')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('8')),
DataCell(Text('Ritesh Patel')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('9')),
DataCell(Text('Ayushi Chaudhari')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('10')),
DataCell(Text('Mayuri Popat')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('11')),
DataCell(Text('Trusha Patel')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('12')),
DataCell(Text('Celine Davla')),
DataCell(Text('')),
],
),
DataRow(
cells: [
DataCell(Text('13')),
DataCell(Text('Jayshree Mehta')),
DataCell(Text('')),
],
),
],
),
],
),
);
}
}
This is my code and I am getting an error about pixel overflow. When I try to solve this error by using SingleChildScrollView, new errors are occurring.
This happens because a widget is bigger than what the screen can display, so it gets off-bounds.
Two solutions that will work: Either wrap your DataTable with a SingleChildScrollView and set the scrollDirection to Axis.horizontal:
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
Or set a fixed columnSpacing:
DataTable(
columnSpacing: 10,
columns: [
Wrap the DataTable widget with SingleChildScrollView then set the scroll direction to horizontal scrollDirection: Axis.horizontal
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class Faculty extends StatefulWidget {
const Faculty({Key? key}) : super(key: key);
#override
_FacultyState createState() => _FacultyState();
}
class _FacultyState extends State<Faculty> {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(' Faculty Info'),
backgroundColor: Color(0xff01A0C7),
),
body: ListView(children: <Widget>[
SizedBox(height: 35),
Center(
child: Text(
'Faculty-Chart',
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
)),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
DataColumn(
label: Text('ID',
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold))),
DataColumn(
label: Text('Name',
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold))),
DataColumn(
label: Text('Contact no',
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold))),
],
rows: [
DataRow(cells: [
DataCell(Text('1')),
DataCell(Text('Amit Thakkar')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('2')),
DataCell(Text('Hemang Thakkar')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('3')),
DataCell(Text('Shrushti Gajjar')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('4')),
DataCell(Text('Dhruvi Thrivedi')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('5')),
DataCell(Text('Deep Kotharia')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('6')),
DataCell(Text('Vaibhai Patel')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('7')),
DataCell(Text('Jaina Patel')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('8')),
DataCell(Text('Ritesh Patel')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('9')),
DataCell(Text('Ayushi Chaudhari')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('10')),
DataCell(Text('Mayuri Popat')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('11')),
DataCell(Text('Trusha Patel')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('12')),
DataCell(Text('Celine Davla')),
DataCell(Text('')),
]),
DataRow(cells: [
DataCell(Text('13')),
DataCell(Text('Jayshree Mehta')),
DataCell(Text('')),
]),
],
),
),
]));
}
}
I'm having a bit of a problem with Flutter's widget placement. Here's the code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
final _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: _scrollController,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _scrollController,
child: DataTable(
//Rows and columns filled with random data
columns: const <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Janine')),
DataCell(Text('43')),
DataCell(Text('Professor')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('William')),
DataCell(Text('27')),
DataCell(Text('Associate Professor')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
],
),
),
//How to make this widget be at the bottom?
const Text('This widget should be at the bottom'),
],
),
),
);
}
}
I have a DataTable and a Text widget, wrapped with a Column and two SingleChilScrollViews in order to have bidirectional scrolling (the table is larger than the screen). I want to place the Text widget on the bottom of the screen. Tinkering with the code, I can do it pretty easily by giving the Column widget a parent Container, and fixing its size to my screen. However, how would I go about sizing it dynamically? I've tried using MediaQuery but the result was not that accurate. This "fix" can be found below:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
final _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: _scrollController,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _scrollController,
child: DataTable(
//Rows and columns filled with random data
columns: const <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Janine')),
DataCell(Text('43')),
DataCell(Text('Professor')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('William')),
DataCell(Text('27')),
DataCell(Text('Associate Professor')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
],
),
),
//How to make this widget be at the bottom?
const Text('This widget should be at the bottom'),
],
),
),
),
);
}
}
Any ideas or suggestions on how to tackle this issue? Thanks.
EDIT
Using the text in the bottomNavigationBar of the Scaffold works as well, however it doens't seem an appropriate solution.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
final _scrollController = ScrollController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
//Rows and columns filled with random data
columns: const <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Janine')),
DataCell(Text('43')),
DataCell(Text('Professor')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('William')),
DataCell(Text('27')),
DataCell(Text('Associate Professor')),
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
],
),
),
],
),
bottomNavigationBar: const Text('Is at the bottom - doesnt seem right'),
);
}
}
i think This might get you resolved your Error.
Code:
Scaffold(
body:SizedBox(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height-100,
width: MediaQuery.of(context).size.width,
child: SingleChildScrollView(
child: Column(
children: [
///// your Scrollabel Data Table will be here
for(int i=0;i<20;i++)
ListTile(
title: Text('Tile $i'),
),
],
),
),
),
const Align(
alignment: Alignment.bottomCenter,
child: Text('Hello I am at the Bottom'),
),
],
),
) ,)
You can use a SingleChildScrollView inside a Listview to achive that.
ListView(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Column(
children: [
//Your table goes here
],
),
),
Text(
//Your bottom text goes here,
),
],
),
I found a more elegant solution while tinkering with my code and the provided answers. I wrapped the Scaffold's body in a Column and used 2 expanded widgets: one for my bottom widget and another one for the ScrollViews and Table. Here's the final body:
body: Column(
children: [
Expanded(
flex: 9,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: _scrollController,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _scrollController,
child: DataTable(
columns: _controller.columns,
rows: _controller.rows,
),
),
),
),
Expanded(
child: Total(_controller.total),
),
],
),
did you try to use BottomSheetNavigtor?
I have a DataTable and I'm trying to make it always show the horizontal and vertical scrollbars.
I managed to always show the vertical scrollbar, but the horizontal scrollbar only shows when I scroll down to the bottom.
Here's my code:
final _scrollController = ScrollController();
final _scrollController2 = ScrollController();
#override
Widget build(BuildContext context) {
return Container(
height: 300,
width: 400,
child: Scrollbar(
controller: _scrollController,
isAlwaysShown: true,
child: SingleChildScrollView(
controller: _scrollController,
scrollDirection: Axis.vertical,
child: Scrollbar(
controller: _scrollController2,
isAlwaysShown: true,
child: SingleChildScrollView(
controller: _scrollController2,
scrollDirection: Axis.horizontal,
child: DataTable(
showCheckboxColumn: true,
columns: [
DataColumn(
label: Text('Name'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
],
rows: List<DataRow>.generate(
20,
(int index) => DataRow(
cells: <DataCell>[
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
],
onSelectChanged: (bool? value) {},
),
),
),
),
),
),
),
);
}
I'm using Flutter 2.2.3 (Channel stable).
I tried a lot of things, but I think I finally got it.
here's the final result: Bidirectional scrolling with fixed scrollbar
I used adaptive_scrollbar v2.1.0 to get this result.
Source Code
import 'package:flutter/material.dart';
import 'package:adaptive_scrollbar/adaptive_scrollbar.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Bidirectional Scrollbars',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
final _verticalScrollController = ScrollController();
final _horizontalScrollController = ScrollController();
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
height: 300,
width: 700,
child: AdaptiveScrollbar(
underColor: Colors.blueGrey.withOpacity(0.3),
sliderDefaultColor: Colors.grey.withOpacity(0.7),
sliderActiveColor: Colors.grey,
controller: _verticalScrollController,
child: AdaptiveScrollbar(
controller: _horizontalScrollController,
position: ScrollbarPosition.bottom,
underColor: Colors.blueGrey.withOpacity(0.3),
sliderDefaultColor: Colors.grey.withOpacity(0.7),
sliderActiveColor: Colors.grey,
child: SingleChildScrollView(
controller: _verticalScrollController,
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
controller: _horizontalScrollController,
scrollDirection: Axis.horizontal,
child: Padding(
padding: const EdgeInsets.only(right: 8.0, bottom: 16.0),
child: DataTable(
showCheckboxColumn: true,
columns: [
DataColumn(
label: Text('Name'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Name'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
],
rows: List<DataRow>.generate(
20,
(int index) => DataRow(
cells: <DataCell>[
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
],
onSelectChanged: (bool? value) {},
),
),
),
),
),
),
),
),
),
);
}
}
I want to create a viewport that could be horizontally and vertically scrolled. I am able to achieve this by using two nested SingleScrollChildView. The problem is that the horizontal scrollbar is not attached to the viewport as desired but rather it is attached/present at the bottom vertically which is expected. Is there a way to achieve such a behavior? Please be gentle as I am still learning this framework. Here is the code snippet:
Scrollbar(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Scrollbar(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: CustomViewPort(),
),
),
),
),
Like this?
Bidirectional scrolling with fixed scrollbar
I used adaptive_scrollbar v2.1.0 to get this result.
Source Code
import 'package:flutter/material.dart';
import 'package:adaptive_scrollbar/adaptive_scrollbar.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Bidirectional Scrollbars',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
final _verticalScrollController = ScrollController();
final _horizontalScrollController = ScrollController();
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
height: 300,
width: 700,
child: AdaptiveScrollbar(
underColor: Colors.blueGrey.withOpacity(0.3),
sliderDefaultColor: Colors.grey.withOpacity(0.7),
sliderActiveColor: Colors.grey,
controller: _verticalScrollController,
child: AdaptiveScrollbar(
controller: _horizontalScrollController,
position: ScrollbarPosition.bottom,
underColor: Colors.blueGrey.withOpacity(0.3),
sliderDefaultColor: Colors.grey.withOpacity(0.7),
sliderActiveColor: Colors.grey,
child: SingleChildScrollView(
controller: _verticalScrollController,
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
controller: _horizontalScrollController,
scrollDirection: Axis.horizontal,
child: Padding(
padding: const EdgeInsets.only(right: 8.0, bottom: 16.0),
child: DataTable(
showCheckboxColumn: true,
columns: [
DataColumn(
label: Text('Name'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Name'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
DataColumn(
label: Text('Year'),
),
],
rows: List<DataRow>.generate(
20,
(int index) => DataRow(
cells: <DataCell>[
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
DataCell(
Text('Row $index'),
),
],
onSelectChanged: (bool? value) {},
),
),
),
),
),
),
),
),
),
);
}
}
The heights of widgets in a DataTable DataCell can vary:
DataCell(Text('Professor\nProfessor\nProfessor\nProfessor\nProfessor\nProfessor\n'))
But if you add the data as a Column, the cell overflows. Why? And how to fix it?
DataRow(
cells: <DataCell>[
DataCell(Text('Janine')),
DataCell(Text('43')),
DataCell(Column(mainAxisSize: MainAxisSize.min, children: [
Text("Professor"),
Text("Professor"),
Text("Professor"),
Text("Professor"),
])),
// DataCell(Text('Professor\nProfessor\nProfessor\nProfessor\nProfessor\nProfessor\n')),
],
),
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: MyStatelessWidget(),
),
);
}
}
/// This is the stateless widget that the main application instantiates.
class MyStatelessWidget extends StatelessWidget {
MyStatelessWidget({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DataTable(
columns: const <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('Sarah')),
DataCell(Text('19')),
DataCell(Text('Student')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('Janine')),
DataCell(Text('43')),
DataCell(Column(mainAxisSize: MainAxisSize.min, children: [
Text("Professor"),
Text("Professor"),
Text("Professor"),
Text("Professor"),
])),
// DataCell(Text('Professor\nProfessor\nProfessor\nProfessor\nProfessor\nProfessor\n')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('William')),
DataCell(Text('27')),
DataCell(Text('Associate Professor')),
],
),
],
);
}
}
You need to wrap your column with SingleChildScrollView.
Here is my solution.
DataCell(Expanded(
child: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, children: [
Text("Professor"),
Text("Professor"),
Text("Professor"),
Text("Professor"),
]),
),
))