同步 ListView 滚动位置
Synchronising ListView Scroll Positions
我正在尝试为该屏幕提供特定的滚动行为。每行都有使用 BLoC 模式提供给它的数据。
屏幕左侧只需要垂直滚动,而右侧需要水平和垂直滚动。
我目前通过为垂直滚动和共享 BLoC 使用两个单独的列表视图来做到这一点。然后将右侧的小部件包裹在向相反方向移动的列表视图中。
我需要同步垂直和水平列表视图(以及将来可能的滚动视图),但未能成功确保滚动位置保持同步。如何同步多个列表视图位置?这是我要执行的操作的代码片段:
class ComposePage extends StatefulWidget {
@override
_ComposePageState createState() => _ComposePageState();
}
class _ComposePageState extends State<ComposePage> {
final TrackingScrollController _scrollController = TrackingScrollController();
@override
Widget build(BuildContext context) {
return Container(
child: NotificationListener<ScrollNotification>(
onNotification: (notification) {
print("SCROLL");
_scrollController.position.setPixels(notification.metrics.pixels);
for (ScrollPosition position in _scrollController.position)
position.setPixels(notification.metrics.pixels);
},
child: Column(
verticalDirection: VerticalDirection.up,
children: <Widget>[
Expanded(
flex: 8,
child: Material(
type: MaterialType.canvas,
elevation: 1.0,
child: _buildBuildComposeContent(_scrollController),
),
),
Expanded(
flex: 1,
child: Material(
type: MaterialType.canvas,
elevation: 20.0,
child: ControlsHeader(),
),
)
],
),
),
color: Colors.green,
);
}
_buildBuildComposeContent(TrackingScrollController scrollController) {
return Container(
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: _buildLabelArea(scrollController),
),
Expanded(
flex: 7,
child: _buildEditArea(scrollController),
),
],
),
);
}
Column _buildLabelArea(TrackingScrollController controller) {
return Column(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.pink,
),
),
Expanded(
flex: 8,
child: ListView(
scrollDirection: Axis.vertical,
controller: controller,
children: <Widget>[
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
],
),
),
],
);
}
Column _buildEditArea(TrackingScrollController controller) {
return Column(
children: <Widget>[
Expanded(
flex: 1,
child: Playhead(),
),
Expanded(
flex: 8,
child: Container(
child: ListView(
scrollDirection: Axis.vertical,
controller: controller,
children: <Widget>[
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
],
),
),
),
],
);
}
}
我通常使用 linked_scroll_controller 来达到这个目的。
查看 this article 了解详情。
我正在尝试为该屏幕提供特定的滚动行为。每行都有使用 BLoC 模式提供给它的数据。
屏幕左侧只需要垂直滚动,而右侧需要水平和垂直滚动。
我目前通过为垂直滚动和共享 BLoC 使用两个单独的列表视图来做到这一点。然后将右侧的小部件包裹在向相反方向移动的列表视图中。
我需要同步垂直和水平列表视图(以及将来可能的滚动视图),但未能成功确保滚动位置保持同步。如何同步多个列表视图位置?这是我要执行的操作的代码片段:
class ComposePage extends StatefulWidget {
@override
_ComposePageState createState() => _ComposePageState();
}
class _ComposePageState extends State<ComposePage> {
final TrackingScrollController _scrollController = TrackingScrollController();
@override
Widget build(BuildContext context) {
return Container(
child: NotificationListener<ScrollNotification>(
onNotification: (notification) {
print("SCROLL");
_scrollController.position.setPixels(notification.metrics.pixels);
for (ScrollPosition position in _scrollController.position)
position.setPixels(notification.metrics.pixels);
},
child: Column(
verticalDirection: VerticalDirection.up,
children: <Widget>[
Expanded(
flex: 8,
child: Material(
type: MaterialType.canvas,
elevation: 1.0,
child: _buildBuildComposeContent(_scrollController),
),
),
Expanded(
flex: 1,
child: Material(
type: MaterialType.canvas,
elevation: 20.0,
child: ControlsHeader(),
),
)
],
),
),
color: Colors.green,
);
}
_buildBuildComposeContent(TrackingScrollController scrollController) {
return Container(
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: _buildLabelArea(scrollController),
),
Expanded(
flex: 7,
child: _buildEditArea(scrollController),
),
],
),
);
}
Column _buildLabelArea(TrackingScrollController controller) {
return Column(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.pink,
),
),
Expanded(
flex: 8,
child: ListView(
scrollDirection: Axis.vertical,
controller: controller,
children: <Widget>[
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackLabel(),
),
],
),
),
],
);
}
Column _buildEditArea(TrackingScrollController controller) {
return Column(
children: <Widget>[
Expanded(
flex: 1,
child: Playhead(),
),
Expanded(
flex: 8,
child: Container(
child: ListView(
scrollDirection: Axis.vertical,
controller: controller,
children: <Widget>[
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
BlocProvider(
bloc: TrackBloc(),
child: TrackView(isEditable: true),
),
],
),
),
),
],
);
}
}
我通常使用 linked_scroll_controller 来达到这个目的。 查看 this article 了解详情。