插件:sticky_headers
https://pub.dev/packages/sticky_headers
代码:
import 'package:flutter/material.dart';
import 'package:sticky_headers/sticky_headers.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, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Widget> timeHeaders = new List<Widget>();
Map<int, List<Widget>> roomRow = new Map<int, List<Widget>>();
double fontSize = 18;
double leadingWidth = 120;
double tileWidth = 84; // CHANGE THIS IF NEEDED
double tileHeight = 30;
double tileBorderWidth = 2;
@override
void initState() {
// TODO: implement initState
super.initState();
timeHeaders.add(
new Container(
height: tileHeight,
width: leadingWidth,
),
);
for (int i = 1; i <= 5; i++) {
timeHeaders.add(
new Container(
height: tileHeight,
width: tileWidth,
decoration: BoxDecoration(
color: Colors.grey[400],
border: Border.all(
color: Colors.black,
width: 2,
),
),
child: Center(
child: Text(
'$i',
style: TextStyle(fontSize: 18),
),
),
),
);
}
for (int i = 0; i < 20; i++) {
roomRow[i + 1] = [
Container(
height: tileHeight,
width: leadingWidth,
child: Center(
child: Text(
'HEADER$i',
style: TextStyle(fontSize: 18),
),
),
),
];
roomRow[i + 1].add(Container(
height: tileHeight,
width: 75,
decoration: BoxDecoration(
color: Colors.lightGreen[300],
border: Border.all(
color: Colors.black,
width: tileBorderWidth,
),
),
child: Container(
margin: EdgeInsets.all(1),
child: Center(
child: Text(
'x',
style: TextStyle(
fontSize: 10,
),
),
),
),
));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
Text('header'),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: (timeHeaders.length.toDouble() - 1) * tileWidth +
leadingWidth,
child: StickyHeader(
header: Row(children: timeHeaders),
content: ListView.separated(
separatorBuilder: (BuildContext context, int index) =>
Divider(),
itemCount: 21,
itemBuilder: (BuildContext context, int index) {
return index == 0
? Container(height: tileHeight)
: Row(children: roomRow[index]);
},
),
),
),
),
),
],
),
),
);
}
}
(我知道日志中存在渲染错误,但这并不影响功能,我的主应用程序运行正常)
基本上,如果垂直滚动(上下滚动),则灰色框会粘在顶部。当水平滚动(从左到右)时,我想对左侧的HEADER进行相同操作。因此,如果我一直向右滚动,则HEADER应该仍然存在