Flutter 上下左右滚动Table
Flutter 上下左右滚动Table
实现功能
- 可以上下左右滚动
- 可修改多个参数配置
- 实现单独选中某个格子
适用性
参数:
double rowWidth; //单个表宽
double rowHeight; //表格高
List<String> titleList = List(); //标题 ["职责", "工作内容", "年度目标", "关联部门", "备注", "1"];
List<List<String>> contentList = List(); //内容列表
List<String> selectList = List(); //选中列表 ["0,1","1,2"]
Color titleBackgroundColor; //标题背景颜色
Color titleTextColor; //标题字体颜色
Color contentBackgroundColor; //列表背景颜色
Color contentTextColor; //列表字体颜色
Color leftFirstTextColor; //左边第一列字体颜色
Color leftFirstBackgroundColor; //左边第一列背景颜色
Color borderColor; //边框颜色
Color allSelectColor; //所有选中颜色
Color selectTextColor; //选中字体颜色
double titleFontSize; //标题字体大小
double contentFontSize; //列表字体大小
double leftFirstFontSize; //左边第一列字体大小
double selectFontSize; //选中字体大小
使用
import 'package:flutter_sams/config/export/export.dart';
import 'package:flutter_sams/view/table_widget.dart';
class TablePage extends StatefulWidget{
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return _TablePageState();
}
}
class _TablePageState extends State<TablePage>{
List<String> titleList = ['日期','项目','日期','项目'];
//列表所有数据
List<List<String>> allList = List();
List<String> contentList = List();
List<List<String>> _getContentList() {
for (int i = 1; i < 20; i++) {
contentList = List();
contentList.add("202$i");
contentList.add("学习2222222255555555555555553333333332$i");
contentList.add("202103$i");
contentList.add("202103$i");
allList.add(contentList);
}
return allList;
}
List<String> _getSelectList(){
List<String> selectList = List();
selectList.add("2,5");
selectList.add("0,1");
selectList.add("3,0");
return selectList;
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Table'),
),
body: Container(
child: TableWidget(titleList,_getContentList(),selectList: _getSelectList(),
onTap: (x,y){
print("外部 x=$x y=$y");
}),
),
);
}
}
Widget全部代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_sams/config/export/export.dart';
class TableWidget extends StatelessWidget {
double rowWidth; //单个表宽
double rowHeight; //表格高
List<String> titleList = List(); //标题 ["职责", "工作内容", "年度目标", "关联部门", "备注", "1"];
List<List<String>> contentList = List(); //内容列表
List<String> selectList = List(); //选中列表 ["0,1","1,2"]
Color titleBackgroundColor; //标题背景颜色
Color titleTextColor; //标题字体颜色
Color contentBackgroundColor; //列表背景颜色
Color contentTextColor; //列表字体颜色
Color leftFirstTextColor; //左边第一列字体颜色
Color leftFirstBackgroundColor; //左边第一列背景颜色
Color borderColor; //边框颜色
Color allSelectColor; //所有选中颜色
Color selectTextColor; //选中字体颜色
double titleFontSize; //标题字体大小
double contentFontSize; //列表字体大小
double leftFirstFontSize; //左边第一列字体大小
double selectFontSize; //选中字体大小
Function onTap;
TableWidget(this.titleList, this.contentList,
{this.rowWidth = 100.0,
this.rowHeight = 48.0,
this.titleBackgroundColor = Colors.greenAccent,
this.titleTextColor = Colors.blueAccent,
this.contentBackgroundColor = Colors.white,
this.contentTextColor = Colors.black87,
this.titleFontSize = 12,
this.contentFontSize = 12,
this.leftFirstBackgroundColor = Colors.white,
this.leftFirstTextColor = Colors.black87,
this.leftFirstFontSize = 12,
this.selectList,
this.borderColor = Colors.black54,
this.allSelectColor = Colors.redAccent,
this.selectTextColor = Colors.black87,
this.selectFontSize = 12,
this.onTap});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: _Table(
this.rowWidth,
this.rowHeight,
this.titleList,
this.contentList,
this.titleBackgroundColor,
this.titleTextColor,
this.contentBackgroundColor,
this.contentTextColor,
this.titleFontSize,
this.contentFontSize,
this.leftFirstBackgroundColor,
this.leftFirstTextColor,
this.leftFirstFontSize,
this.selectList,
this.borderColor,
this.allSelectColor,
this.selectTextColor,
this.selectFontSize,
this.onTap),
);
}
}
class _Table extends StatefulWidget {
double rowWidth; //单个表宽
double rowHeight; //表格高
List<String> titleList; //标题
List<List<String>> contentList;
List<String> selectList; //选中列表 ["0,1","1,2"]
Color titleBackgroundColor;
Color titleTextColor;
Color contentBackgroundColor; //列表背景颜色
Color contentTextColor;
Color leftFirstTextColor; //左边第一列字体颜色
Color leftFirstBackgroundColor; //左边第一列背景颜色
Color borderColor; //边框颜色
Color allSelectColor; //所有选中颜色
Color selectTextColor; //选中字体颜色
double titleFontSize; //标题字体大小
double contentFontSize; //列表字体大小
double leftFirstFontSize; //左边第一列字体大小
double selectFontSize; //选中字体大小
Function onTap;
_Table(
this.rowWidth,
this.rowHeight,
this.titleList,
this.contentList,
this.titleBackgroundColor,
this.titleTextColor,
this.contentBackgroundColor,
this.contentTextColor,
this.titleFontSize,
this.contentFontSize,
this.leftFirstBackgroundColor,
this.leftFirstTextColor,
this.leftFirstFontSize,
this.selectList,
this.borderColor,
this.allSelectColor,
this.selectTextColor,
this.selectFontSize,
this.onTap);
@override
_TableState createState() => _TableState();
}
class _TableState extends State<_Table> {
//定义可控制滚动组件
ScrollController firstColumnController = ScrollController();
ScrollController thirdColumnController = ScrollController();
ScrollController firstRowController = ScrollController();
ScrollController secondedRowController = ScrollController();
//创建第一列行
// double numRowWidth = 100.0; //单个表宽
// double numRowHeight = 48.0; //表格高
// Color titleBackgroundColor = Color(0xFF88DFE4);
// Color titleTextColor = Colors.blueAccent;
//顶部标题
// List<String> titleList = ["职责", "工作内容", "年度目标", "关联部门", "备注", "1"];
//列表所有数据
List<List<String>> allList = List();
List<String> contentList = List();
//左边第一列数据--不包含顶部标题
List<String> leftList = List();
//右边所有数据--不包含顶部标题和第一列数据
List<List<String>> rightList = List();
List<String> rightContentList = List();
// List<String> selectList = List();
List<List<String>> _getContentList() {
for (int i = 0; i < 20; i++) {
contentList = List();
contentList.add("软件质量管理$i");
contentList.add("学习$i");
contentList.add("成为顶尖开发$i");
contentList.add("信息技术事业部$i");
contentList.add("加油$i");
contentList.add("随意添加$i");
allList.add(contentList);
}
return allList;
}
void _getTwoList(List<List<String>> contentList) {
leftList.clear();
rightList.clear();
rightList.clear();
contentList.forEach((itList) {
rightContentList = List();
for (int i = 0; i < itList.length; i++) {
if (i == 0) {
leftList.add(itList[i]);
} else {
rightContentList.add(itList[i]);
}
}
rightList.add(rightContentList);
});
}
List<int> xList = List();
List<int> yList = List();
///第一列数据
List<TableRow> _buildTableColumnOne() {
List<TableRow> returnList = List();
for (int i = 0; i < leftList.length; i++) {
returnList.add(_buildSingleColumnOne(i, leftList[i], leftList.length,
isSelect: widget.selectList.contains("0,$i")));
}
return returnList;
}
//创建tableRows
List<TableRow> _buildTableRow() {
List<TableRow> returnList = new List();
for (int j = 0; j < rightList.length; j++) {
returnList.add(_buildSingleRow(j, rightList[j], false)); //添加行
}
return returnList;
}
///第一行标题 创建单行
List<TableRow> _buildTableOneRow() {
List<TableRow> returnList = new List();
for (int j = 0; j < 1; j++) {
returnList.add(_buildSingleRow(j, widget.titleList, true)); //添加行
}
return returnList;
}
//创建第一列tableRow
TableRow _buildSingleColumnOne(int index, String text, int totalLength,
{bool isSelect = false}) {
return TableRow(children: [
_buildSideBox(index, text, false, isLeftFirst: true, isSelect: isSelect),
]);
}
//创建一行tableRow
TableRow _buildSingleRow(int index, List<String> textList, bool isTitle) {
return TableRow(children: [
for (int i = 0;
i < (isTitle ? textList.length - 1 : textList.length);
i++)
isTitle
? _buildSideBox(i, textList[i + 1], true)
: _buildSideBox(i, textList[i], false,
xx: index,
isSelect: widget.selectList.contains("${i + 1},$index")),
]);
}
//创建单个表格
Widget _buildSideBox(int index, String title, bool isTitle,
{bool isLeftFirst = false, int xx, bool isSelect = false}) {
return Container(
color: isTitle
? widget.titleBackgroundColor
: (isLeftFirst
? isSelect
? widget.allSelectColor
: widget.leftFirstBackgroundColor
: isSelect
? widget.allSelectColor
: widget.contentBackgroundColor),
child: InkWell(
child: SizedBox(
height: widget.rowHeight,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 0.33, color: widget.borderColor),
top: BorderSide(width: 0.33, color: widget.borderColor),
right: BorderSide(width: 0.33, color: widget.borderColor),
left: BorderSide(width: 0.33, color: widget.borderColor),
)),
child: Text(
title,
// maxLines: 1,
// overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: isTitle
? widget.titleFontSize
: (isLeftFirst
? isSelect
? widget.selectFontSize
: widget.leftFirstFontSize
: isSelect
? widget.selectFontSize
: widget.contentFontSize),
color: isTitle
? widget.titleTextColor
: (isLeftFirst
? isSelect
? widget.selectTextColor
: widget.leftFirstTextColor
: isSelect
? widget.selectTextColor
: widget.contentTextColor)),
),
)),
onTap: () {
if (widget.onTap != null) {
int x = 0;
int y = 0;
if (isLeftFirst) {
x = 0;
y = index;
// print("&&x=0 y=$index");
} else {
y = xx;
x = index + 1;
// print("&&x=$x y=$y");
}
widget.onTap(x, y);
}
},
),
);
}
@override
void initState() {
super.initState();
// _getTwoList(_getContentList());
_getTwoList(widget.contentList);
//监听第一列变动
firstColumnController.addListener(() {
if (firstColumnController.offset != thirdColumnController.offset) {
thirdColumnController.jumpTo(firstColumnController.offset);
}
});
//监听第三列变动
thirdColumnController.addListener(() {
if (firstColumnController.offset != thirdColumnController.offset) {
firstColumnController.jumpTo(thirdColumnController.offset);
}
});
//监听第一行变动
firstRowController.addListener(() {
if (firstRowController.offset != secondedRowController.offset) {
secondedRowController.jumpTo(firstRowController.offset);
}
});
//监听第二行变动
secondedRowController.addListener(() {
if (firstRowController.offset != secondedRowController.offset) {
firstRowController.jumpTo(secondedRowController.offset);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: MediaQuery.removePadding(
removeTop: true,
context: context,
child: NotificationListener(
//表格
child: Container(
// padding: EdgeInsets.only(right: 8, left:8, top: 8, bottom: 8),
// margin: EdgeInsets.only(right: 16,left:16),
// height: 209,
// width:375,
// color:Colors.lightGreen,
child: Row(
children: [
//前两列
Container(
width: widget.rowWidth,
// height:200,
child: Column(
children: [
Table(
children: [
TableRow(
children: [
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 0.33, color: widget.borderColor),
top: BorderSide(
width: 0.33, color: widget.borderColor),
right: BorderSide(
width: 0.33, color: widget.borderColor),
left: BorderSide(
width: 0.33, color: widget.borderColor),
),
),
child: Container(
height: widget.rowHeight - 0.33,
color: widget.titleBackgroundColor,
// padding: EdgeInsets.all(10),
child: Center(
child: Text(
widget.titleList[0],
textAlign: TextAlign.center,
style: TextStyle(
color: widget.titleTextColor,
fontSize: widget.titleFontSize),
),
),
),
),
],
),
],
),
//SingleChildScrollView(
Expanded(
child: ListView(
controller: firstColumnController,
children: [
Table(children: _buildTableColumnOne()),
],
),
),
],
),
),
//其余列
Expanded(
child: Container(
// width: 200,
child: Column(children: [
Container(
alignment: Alignment.topLeft,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal, //horizontal
controller: firstRowController,
child: Container(
child: Table(children: _buildTableOneRow()),
width: (widget.rowWidth) *
(widget.titleList.length - 1), //设置列的行宽
)),
),
Expanded(
child: ListView(
controller: thirdColumnController,
children: [
SingleChildScrollView(
controller: secondedRowController,
scrollDirection: Axis.horizontal, //horizontal
child: Row(
children: [
Container(
child: Table(children: _buildTableRow()),
width: (widget.rowWidth) *
(widget.titleList.length - 1), //设置列的行宽
)
],
),
),
],
),
),
]),
),
),
],
),
),
),
));
}
@override
void dispose() {
// TODO: implement dispose
firstColumnController?.dispose();
thirdColumnController?.dispose();
firstRowController?.dispose();
secondedRowController?.dispose();
super.dispose();
}
}
存在缺陷
表格宽度暂时无法自动适配,只能自己传参修改
引用
感谢这位老铁的分享,此组件是在这基础上进行完善。
[https://blog.csdn.net/zzy123zzy123_/article/details/108867596]
结尾
欢迎各位留言