在我的flutter应用程序中,我想创建一个时间表小部件,它将水平和垂直滚动相应的标题。时间表应该有'天'作为水平标题和'周期'作为垂直标题。我使用链接_滚动_控制器来实现这一点。我使用flutter块作为状态管理。时间表工作正常,正如我所期望的,但问题来了,当我改变屏幕方向(即屏幕旋转时),误差如下。
======== Exception caught by widgets library =======================================================
The following assertion was thrown building SingleChildScrollView(dependencies: [Directionality]):
_LinkedScrollPosition cannot change controllers once created.
'package:linked_scroll_controller/linked_scroll_controller.dart':
Failed assertion: line 142 pos 12: 'linkedPosition.owner == this'
The relevant error-causing widget was:
SingleChildScrollView SingleChildScrollView:
When the exception was thrown, this was the stack:
#2 _LinkedScrollController.attach (package:linked_scroll_controller/linked_scroll_controller.dart:142:12)
#3 ScrollableState.didUpdateWidget (package:flutter/src/widgets/scrollable.dart:561:34)
#4 StatefulElement.update (package:flutter/src/widgets/framework.dart:5142:55)
#5 Element.updateChild (package:flutter/src/widgets/framework.dart:3660:15)
下面是我的代码:
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
import '../../time_table.dart';
class MyTimeTable extends StatefulWidget {
final SchoolClass selClass;
MyTimeTable({Key? key, required this.selClass}) : super(key: key);
@override
State<MyTimeTable> createState() => _MyTimeTableState();
}
class _MyTimeTableState extends State<MyTimeTable> {
late LinkedScrollControllerGroup _horizontalControllersGroup;
late ScrollController _horizontalBody;
late ScrollController _horizontalHeader;
late LinkedScrollControllerGroup _verticalControllersGroup;
late ScrollController _verticalBody;
late ScrollController _verticalHeader;
List<dynamic>? periodList;
List<dynamic>? timeTableList;
final List<String> rowEntries = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday",];
@override
Widget build(BuildContext context) {
context.read<ClassBloc>().add(FetchPeriodTimeTable(widget.classId));
_horizontalControllersGroup = LinkedScrollControllerGroup();
_horizontalBody = _horizontalControllersGroup.addAndGet();
_horizontalHeader = _horizontalControllersGroup.addAndGet();
_verticalControllersGroup = LinkedScrollControllerGroup();
_verticalBody = _verticalControllersGroup.addAndGet();
_verticalHeader = _verticalControllersGroup.addAndGet();
return MaterialApp(
home: Scaffold(
resizeToAvoidBottomInset: false,
appBar: sizedAppBar,
body: SafeArea(
child: Container(
child: Column(
children: [
Row(
children: <Widget>[
SizedBox(height: cellHeight,width: cellWidth,...),
Expanded(
child: Container(// horizontal day header
height: 65,
width: 400,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _horizontalHeader,
child: HeaderContainer(rowEntries: rowEntries),
),
),
)
],
),
Expanded(
child: Container(
child: Row(
children: <Widget>[
Container(// vertical period header
width: 100,
child: SingleChildScrollView(
controller: _verticalHeader,
child: getColumnContainer(),
),
),
Expanded( // data grid
child: SingleChildScrollView(
controller: _verticalBody,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: _horizontalBody,
child: getBodyContainer(),
),
),
)
],
),
),
),
],
),
),
),
),
);
}
getColumnContainer() { // vertical period header
return BlocBuilder<ClassBloc, ClassState>(
builder: (context, state) {
if(state is PeriodTimeTableList) {
periodList = state.item1MultiList;
}
if(periodList != null) {
int numberOfRows = periodList!.length;
return ColumnContainer(
colEntries: periodList!,
);
}
return const SizedBox();
},
);
}
getBodyContainer() {
return BlocBuilder<ClassBloc, ClassState>(
builder: (context, state) {
if(state is PeriodTimeTableList) {
periodList = state.item1MultiList;
timeTableList = state.item2MultiList;
}
if(periodList != null && timeTableList != null) {
int _numberOfColumns = rowEntries.length;
int _numberOfLines = periodList!.length;
int itemCounter = 0;
return BodyContainer(
rowEntries: rowEntries,
colEntries: periodList!,
dataList: timeTableList!,
);
}
return SizedBox();
},
);
}
}
Flutter块:
class ClassBloc extends Bloc<ClassEvent, ClassState> {
final MyApi myApi;
ClassBloc({required this.myApi}) : super(ClassInitial()) {
on<FetchPeriodTimeTable>((event, emit) async {
var result = await myApi.getPeriodTimeTable(event.classId);
List<dynamic> periodList = [];
periodList = result['periodList'];
List<dynamic> timeTableList = [];
timeTableList = result['timeTableList'];
emit(PeriodTimeTableList(item1MultiList: periodList,item2MultiList: timeTableList));
});
}
Future<void> updateTimeTable(TimeTable timeTable) async {
try { // to save add/edit function and update the list
var result = await myApi.updateTimeTable(timeTable);
if(result['status'] == 1) {
List<dynamic> periodList = [];
periodList = result['periodList'];
List<dynamic> timeTableList = [];
timeTableList = result['timeTableList'];
emit(const TimeTableCreated());
emit(PeriodTimeTableList(item1MultiList: periodList,item2MultiList: timeTableList));
} else if(result['index'] == 2) {
emit(const TimeTableNotCreated());
} else {
emit(const ErrorDialog(title: 'Sorry',message: 'Something went wrong'));
}
} catch (error) {
emit(const ErrorDialog(title: 'Sorry',message: 'Something went wrong'));
}
}
}
1条答案
按热度按时间nbysray51#
您应该为每个使用scrollcontroller的小部件添加唯一的键