maylau-cbl / flutter_horizontal_data_table Goto Github PK
View Code? Open in Web Editor NEWFlutter Fixed Column Horizontal Datatable Widget
Home Page: https://pub.dev/packages/horizontal_data_table
License: MIT License
Flutter Fixed Column Horizontal Datatable Widget
Home Page: https://pub.dev/packages/horizontal_data_table
License: MIT License
On the table, I'm trying to set the scrollbar colors to my own value by assigning a color.
When I try to do this, I get "Invalid constant value" . Is there a workaround so I can set the color dynamically?
Color mycolor = Colors.blue
return Container(
// height: MediaQuery.of(context).size.height-240,
child: HorizontalDataTable(
leftHandSideColumnWidth: 150,
rightHandSideColumnWidth: (columns.length -
2 -
columns.where((element) => element['hide'] == true).length) *
150,
isFixedHeader: true,
headerWidgets: _getTitleWidget(),
leftSideItemBuilder: _generateFirstColumnRow,
rightSideItemBuilder: _generateRightHandSideColumnRow,
itemCount: data.length,
rowSeparatorWidget: const Divider(
color: Colors.black54,
height: 1.0,
thickness: 0.0,
),
leftHandSideColBackgroundColor: Color(0xFFFFFFFF),
rightHandSideColBackgroundColor: Color(0xFFFFFFFF),
verticalScrollbarStyle: const ScrollbarStyle(
thumbColor: Colors.yellow,
isAlwaysShown: true,
thickness: 4.0,
radius: Radius.circular(5.0),
),
horizontalScrollbarStyle: const ScrollbarStyle(
thumbColor: mycolor,
isAlwaysShown: true,
thickness: 4.0,
radius: Radius.circular(5.0),
),
enablePullToRefresh: false,
refreshIndicator: const WaterDropHeader(),
refreshIndicatorHeight: 60,
),
);
}
Just like fix header we need fix footer to show data like total or count of values in that column
I just upgraded from 1.0.9 to 2.0 and get this whenever I close a horizontal data table:
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following JSNoSuchMethodError was thrown while finalizing the widget tree:
NoSuchMethodError: invalid member on null: 'setRefreshController'
When the exception was thrown, this was the stack:
packages/horizontal_data_table/horizontal_data_table.dart 191:33 dispose
packages/flutter/src/widgets/framework.dart 4901:11 unmount
packages/flutter/src/widgets/framework.dart 2026:12 [_unmount]
packages/flutter/src/widgets/framework.dart 2024:7
packages/flutter/src/widgets/framework.dart 6151:23 visitChildren
...
Can you tell me if there is a way to implement saving and restoring the scroll position?
Describe the bug
Fix FlatButton to TextButton in example project
Platform
All supported platform
Screen Captures or Debug Log
N/A
Additional context
N/A
没有下拉,没法刷新数据啊宝
必须在外层包裹一个有高度的容器?
只有设置水平分隔线,可以设置垂直分隔线吗?
Describe the Feature
Just mark it here. Since RawScrollbar is not ready on flutter stable channel, will keep it on beta pre-release of the pub.dev.
Describe the Solution
will merge beta branch to master when flutter stable support
How i can add an filter textfield in header column for filter data
一定要设置表格高度吗?怎么让表格本身多高就显示多高?
I have download the project but it was not runnable,
can you upload runnable example to speed up the learning curve of new dev,
thanks so much
Centralise the discussion regarding to pull to refresh feature
Since there are many issues related to this feature, I open a new issue here.
The new branches feature/pull-to-refresh is handling this feature. Still working on the read me and example for that, but anyone is interested on this feature or have an idea to contribute this please feel free to checkout the branch and create PR.
As previous discussion, since the way of the implementation and the performance consideration, the pull will only available for the right hand side list at the moment. The pull feature is by pull-to-refresh package and a little bit customize.
Here is the preview:
Feature request
Need sort on header column
Need pagination(Number of rows per page and next-prev button to move along pages)
Hi, it is possible to add a horizontal and vertical scrollbar? I think that with scrollbar widget might work.
Thanks.
支持下拉与加载更多的配置吗,另外如果列表有上千条上万条数据需要分页加载显示,性能会不会有影响
Describe the bug
Description of what the bug is.
Platform
Please describe the affected platfrom(eg. IOS, Android, Web, Window, Mac, Linux)
Screen Captures or Debug Log
If applicable, add screenshots or debug log to help explain your problem.
Additional context
Add any other context about the problem here.
I am running into an issue where it's only showing the first 7 column/headers that I've defined?
I tried hard coding like this to simplify and right now, it stops at 'col 7' ?
List _getTitleWidget() {
return [
_getTitleItemWidget('col 1', 100),
_getTitleItemWidget('col 2', 100),
_getTitleItemWidget('col 3', 100),
_getTitleItemWidget('col 4', 100),
_getTitleItemWidget('col 5', 100),
_getTitleItemWidget('col 6', 100),
_getTitleItemWidget('col 7', 100),
_getTitleItemWidget('col 8', 100),
_getTitleItemWidget('col 9', 100),
];
Can this be changed to support dynamic # of header/columns??
How to make horizontalDataTable height adjust to number of rows? Right now height is matched to parent widget even though table has one row
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:horizontal_data_table/horizontal_data_table.dart';
import 'package:horizontal_data_table/refresh/pull_to_refresh/src/smart_refresher.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@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 StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
HDTRefreshController _hdtRefreshController = HDTRefreshController();
static const int sortName = 0;
static const int sortStatus = 1;
bool isAscending = true;
int sortType = sortName;
@override
void initState() {
user.initData(20);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _getBodyWidget(),
);
}
Widget _getBodyWidget() {
return Container(
child: HorizontalDataTable(
leftHandSideColumnWidth: 100,
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),
verticalScrollbarStyle: const ScrollbarStyle(
thumbColor: Colors.yellow,
isAlwaysShown: true,
thickness: 0.0,
radius: Radius.circular(5.0),
),
horizontalScrollbarStyle: const ScrollbarStyle(
thumbColor: Colors.red,
isAlwaysShown: true,
thickness: 0.0,
radius: Radius.circular(5.0),
),
enablePullToRefresh: true,
refreshIndicator:
/*
const WaterDropHeader(),
*/
CustomHeader(
builder: (context, mode) {
Widget body = Text("");
if (mode == RefreshStatus.idle) {
body = Text("pull down refresh");
} else if (mode == RefreshStatus.refreshing) {
body = CupertinoActivityIndicator();
} else if (mode == RefreshStatus.canRefresh) {
body = Text("release to refresh");
} else if (mode == RefreshStatus.completed) {
body = Text("refreshCompleted!");
}
return Container(
height: 60.0,
child: Center(
child: body,
),
);
},
),
refreshIndicatorHeight: 60,
onRefresh: () async {
//Do sth
await Future.delayed(const Duration(milliseconds: 500));
_hdtRefreshController.refreshCompleted();
},
htdRefreshController: _hdtRefreshController,
),
height: MediaQuery.of(context).size.height,
);
}
List<Widget> _getTitleWidget() {
return [
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
),
child: _getTitleItemWidget(
'Name' + (sortType == sortName ? (isAscending ? '↓' : '↑') : ''),
100),
onPressed: () {
sortType = sortName;
isAscending = !isAscending;
user.sortName(isAscending);
setState(() {});
},
),
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
),
child: _getTitleItemWidget(
'Status' +
(sortType == sortStatus ? (isAscending ? '↓' : '↑') : ''),
100),
onPressed: () {
sortType = sortStatus;
isAscending = !isAscending;
user.sortStatus(isAscending);
setState(() {});
},
),
_getTitleItemWidget('Phone', 200),
_getTitleItemWidget('Register', 100),
_getTitleItemWidget('Termination', 200),
];
}
Widget _getTitleItemWidget(String label, double width) {
return Container(
child: Text(label, style: TextStyle(fontWeight: FontWeight.bold)),
width: width,
height: 56,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
);
}
Widget _generateFirstColumnRow(BuildContext context, int index) {
return Container(
child: Text(user.userInfo[index].name),
width: 100,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
);
}
Widget _generateRightHandSideColumnRow(BuildContext context, int index) {
return Row(
children: <Widget>[
Container(
child: Row(
children: <Widget>[
Icon(
user.userInfo[index].status
? Icons.notifications_off
: Icons.notifications_active,
color:
user.userInfo[index].status ? Colors.red : Colors.green),
Text(user.userInfo[index].status ? 'Disabled' : 'Active')
],
),
width: 100,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
Container(
child: Text(user.userInfo[index].phone),
width: 200,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
Container(
child: Text(user.userInfo[index].registerDate),
width: 100,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
Container(
child: Text(user.userInfo[index].terminationDate),
width: 200,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
],
);
}
}
User user = User();
class User {
List<UserInfo> userInfo = [];
void initData(int size) {
for (int i = 0; i < size; i++) {
userInfo.add(UserInfo(
"User_$i", i % 3 == 0, '+001 9999 9999', '2019-01-01', 'N/A'));
}
}
///
/// Single sort, sort Name's id
void sortName(bool isAscending) {
userInfo.sort((a, b) {
int aId = int.tryParse(a.name.replaceFirst('User_', '')) ?? 0;
int bId = int.tryParse(b.name.replaceFirst('User_', '')) ?? 0;
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_', '')) ?? 0;
int bId = int.tryParse(b.name.replaceFirst('User_', '')) ?? 0;
return (aId - bId);
} else if (a.status) {
return isAscending ? 1 : -1;
} else {
return isAscending ? -1 : 1;
}
});
}
}
class UserInfo {
String name;
bool status;
String phone;
String registerDate;
String terminationDate;
UserInfo(this.name, this.status, this.phone, this.registerDate,
this.terminationDate);
}
We have screen where multiple types of widgets are shown like table, pie chart, bar chart etc. All these widgets are added in ListView. Problem is that when i scroll inside table and reached to top or bottom then scroll in listview is not worked. I have to scroll outside of table to get scroll in ListView worked. Any solution for this?
I have attached use case below.
Hello,
when use horizontal scrolling my image.memory(base64String) dissappears, any solution ?
Describe the Problem
Please tell me about the setting of "scrollPhysics".
"BouncingScrollPhysics" is set in "scrollPhysics".
However, when scrolling the line, the positions of "leftSideItemBuilder" and "rightSideItemBuilder" are misaligned.
"RightSideItemBuilder" returns to its initial position while scrolling "leftSideItemBuilder".
Is there a way to link "leftSideItemBuilder" and "rightSideItemBuilder"?
你好,可以加上上拉加载更多功能吗?
毕竟表格的话会有很多数据,如果一次性加载完太消耗性能了。
Thanks for this great package.
I noticed in the video that when you school horizontally a shadow appears at the right side of the first column, but when it doesn't appear when using the code example you provided. Can you please add that shadow.
Describe the Feature
Null-Safety Support
Describe the Solution
I will turn this issue as high priority in order to support the new flutter version asap.
I have a table that is dynamically generated with data. When new data is added it would be great if the table would automatically scroll to the right to display new data.
I was able to make this work locally by adding a function called onRightHandSideColumnWidthChange
that passed in the _rightHorizontalScrollController
. Then in the callback I added this code.
onRightHandSideColumnWidthChange: (ScrollController _controller) {
if (rightHandSideColumnWidth + leftHandSideColumnWidth >=
containerWidth) {
_controller.animateTo(_controller.position.maxScrollExtent + leftHandSideColumnWidth,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 100));
}
}
This is a obviously a very specific use case but it might be good to expose onRightHandSideColumnWidthChange
. Thoughts?
Describe the bug
I am using horizontal_data_table: ^ 3.5.0
. I am quite confused because I have not get to remove an Extra Padding that is putting the Widget just before displaying the Header (see Graph 1). A proof that this extra padding is specifically due to Horizontal_Data_Table
, is that if I change this function to a simple text that says 'Hello' that padding stops appearing. How can I remove this padding?
The code I am using in Horizontal Data Table is as follows:
StreamBuilder(
stream: estanquesBloc.estanqueLoteStream,
builder: (BuildContext context, AsyncSnapshot<List<LoteModel>> snapshot){
if (snapshot.hasData) {
loteList = snapshot.data;
if (loteList!.isEmpty) return _imagenInicial(context);
return HorizontalDataTable(
leftHandSideColumnWidth: _size.width*(0.13+0.045),
rightHandSideColumnWidth: _size.width*(0.1*7+0.15),
isFixedHeader: true,
headerWidgets: _titulos(),
leftSideItemBuilder: (context, i) =>_crearItemsPrimeraColumna(context, loteList![i]),
rightSideItemBuilder: (context, i) =>_crearItemsSiguientesColumnas(context, loteList![i]),
itemCount: loteList!.length,
rowSeparatorWidget: Container(
height: 10.0,
color: Colors.grey[200],
),
htdRefreshController: _hdtRefreshController,
);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return const Center (child: Image(image: AssetImage('assets/Aplians-fish-Preloader.gif'), height: 100.0,));
}
);
If I change HorizontalDataTable by a Hello Text the result is as follows:
The code to demonstrate that the Padding is due to HorizontalDataTable Widget is as follows:
StreamBuilder(
stream: estanquesBloc.estanqueLoteStream,
builder: (BuildContext context, AsyncSnapshot<List<LoteModel>> snapshot){
if (snapshot.hasData) {
loteList = snapshot.data;
if (loteList!.isEmpty) return _imagenInicial(context);
return Text('Hello');
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return const Center (child: Image(image: AssetImage('assets/Aplians-fish-Preloader.gif'), height: 100.0,));
}
);
Platform
I'm testing on IOS and Android
Screen Captures or Debug Log
It was included
Additional context
It was included
Hi,
I wanted to create an Arabic (right-to-left) app.
how to show right-to-left (RTL) data-table in Flutter?
I tried to pop up a dialog box from data table cell by user clicking, but unable to pass the cell content variable to 'onTap' or 'onPressed'. Neither success on both "_generateFirstColumnRow," or "_generateRightHandSideColumnRow".
Any advice? Thanks.
Ivan Law
I'm trying to change some style in the screen depending on user scrolling the horizontal data table, is there's a way to add an event to the table like "onScroll" or "onScrollEnding" to trigger a function or set the state to refresh the page and update the UI?
This is caused by Material widget (lines: 131,158,182) not accepting elevation below 0 generated by private function _getElevation.
The solution for me is just to add .abs() function after calling _gelElevation.
/* headerWidgets: <Widget>[
_getTitleItemWidget('Project Name', width / 5),
_getTitleItemWidget('Start Date', width / 2.5),
/* _getTitleItemWidget('Due Date', width / 2.5),
_getTitleItemWidget('Bulling Type', width / 2.5),
_getTitleItemWidget('Manager', width / 2.5),
_getTitleItemWidget('Status', width / 2.5), */
], */
leftHandSideColumnWidth: width / 5,
rightHandSideColumnWidth: width * 2,
isFixedHeader: true,
itemCount: 2,
elevation: 3.0,
rightSideChildren: [
Container(
child: Text("dsas"),
width: width / 2.5,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
Container(
child: Text("ddsadsa"),
width: width / 2.5,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
],
leftSideChildren: [
Container(
child: Text(""),
width: width / 2.5,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
Container(
child: Text(""),
width: width / 2.5,
height: 52,
padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft,
),
],
),```
I need to wrap HorizontalDataTable within a Column Widget for adding a TextField above table. But it is showing "renderflex overflowed-by-infinity-pixels-on-the-bottom"
I could use container for each column header, but that leaves a slight line between each header. Any way to set the header row with background color?
Describe the Feature
I need to be able to adjust the width of each column at any time by dragging.
Thanks.
Wouldn't it be better to improve the existing DataTable widget instead of creating a new widget that does the same thing but adds a few features?
Context: Found this candidate, but the arguments don't match.
const Divider({
^
It's perfect if you support pull-up refresh
Describe the bug
Horizontal scrollbar disappears when scrolling vertically, even with isAlwaysShown
set to true.
Platform
Web, run with flutter run -d chrome
.
Screen Captures or Debug Log
First screenshot shows horizontal and vertical scrollbars visible on initial render
Second screenshot shows missing horizontal scrollbar after starting to scroll vertically.
Additional context
This is fairly important for web users, who may be using a physical mouse and thus need to drag the scrollbar to scroll horizontally.
I think I have a fix locally and I'll create a PR.
hi there
thanks for your effort.
i has try to return Row in leftSideItemBuilder to make two column fixed, but there is something wrong with the header. the first item from the headerWidgets go to the left side as expected, but the second item goes to the right side even when the width of leftHandSideColumnWidth is big enough to put two column in. is there an other way to do that? sorry for the lousy english, hope you can understand what i am trying to say. thanks.
return Container(
height: ((contentList.length + 1) * 46).toDouble(),
padding: EdgeInsets.zero,
child: HorizontalDataTable(
leftHandSideColumnWidth: 100,
rightHandSideColumnWidth: ((titleList.length - 1) * 100).toDouble(),
isFixedHeader: true,
headerWidgets: _getTitleWidget(titleList),
leftSideItemBuilder: _generateFirstColumnRow,
rightSideItemBuilder: _generateRightSideColumnRow,
itemCount: contentList.length,
rowSeparatorWidget: const Divider(
color: Colors.transparent,
height: 0.0,
thickness: 0.0,
),
leftHandSideColBackgroundColor: Colors.white,
rightHandSideColBackgroundColor: Colors.white,
enablePullToRefresh: false,
),
);
Applied the library but I couldn't run the project due to this error.
`Error: The method 'RawScrollbar' isn't defined for the class 'CustomScrollBar'.
Describe the bug
The header disappears when the table is scrollable vertically. However, the moment I scroll down or up it reappears, and as soon as the screen stops moving, it disappears again. The bug seems to trigger in portrait and landscape mode
Platform
iPhone and iPad, when Flutter Web is launched, and the website is accessed from safari
Screen Captures or Debug Log
iPad Po (11-inch) - 3rd generation, iOS 15.2 in landscape mode
iPhone 13 - iOS 15.2 in portrait mode
Additional context
The problem does not occur on Safari on mac. It happens sometimes that the header works at the beginning, but staying on the board for a few seconds and scrolling, the problem reappears
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.