'GlobalKey().currentContext' 在 ListWheelScrollView 中为 null
'GlobalKey().currentContext' in ListWheelScrollView is null in flutter
我正在尝试 select/scroll 在单击按钮时自动转到 ListWheelScrollView 中的特定元素。它适用于当前页面中显示的元素。但是我一直遇到由于延迟加载导致列表超出屏幕的问题。
由于 ListWheelScrollView 中的小部件未呈现,当尝试滚动到屏幕之外时会为当前上下文抛出 null 错误。
我尝试过的:
尝试 1:我尝试将 ListWheelScrollView 包装在 SingleChildScrollView 小部件中。没有解决问题。
尝试 2:尝试使用 (scrollable_positioned_list )。它用于 ListView 而不是 ListWheelScrollView。
这是我的源代码。
import 'package:flutter/material.dart';
// import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
void main() {
runApp(
const MaterialApp(home: StatefulWidgetsExample()), // use MaterialApp
);
}
class StatefulWidgetsExample extends StatefulWidget {
const StatefulWidgetsExample({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _StatefulWidgetsExampleState();
}
class _StatefulWidgetsExampleState extends State<StatefulWidgetsExample> {
final itemKey = GlobalKey();
final scrollController = ScrollController();
Future animateTo() async {
BuildContext? context = itemKey.currentContext;
scrollController.position.ensureVisible(
itemKey.currentContext!.findRenderObject()!,
duration: const Duration(seconds: 1),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List Wheel"),
),
body: Column(
children: [
Expanded(
child: Center(
child: Row(
children: [
SizedBox(
height: 500,
width: 200,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
height: 500,
width: 200,
child: ListWheelScrollView(
controller: scrollController,
itemExtent: 100,
children: <Widget>[
const MaterialButton(
onPressed: null,
child: Text(
"Item 1",
textAlign: TextAlign.start,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 2",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 3",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 4",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
Container(
alignment: Alignment.center,
key: itemKey,
child: const MaterialButton(
onPressed: null,
child: Text(
"Item 5",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 6",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 7",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 8",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
],
clipBehavior: Clip.hardEdge,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: MaterialButton(
color: Colors.red,
onPressed: animateTo,
child: const Text("Animate to"),
),
),
],
),
),
),
],
),
);
}
}
任何 help/suggestion 将不胜感激。谢谢!
在做了一些基础工作后,我发现可以通过 FixedExtentScrollController
来完成。
如果有人面临同样的问题,这里是完整的例子。
void main() {
runApp(
const MaterialApp(home: StatefulWidgetsExample()), // use MaterialApp
);
}
class StatefulWidgetsExample extends StatefulWidget {
const StatefulWidgetsExample({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _StatefulWidgetsExampleState();
}
class _StatefulWidgetsExampleState extends State<StatefulWidgetsExample> {
final FixedExtentScrollController scrollController =
FixedExtentScrollController();
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
Widget buildCard(int i) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 200,
height: 200,
color: Colors.red,
child: Center(
child: Text(
"Widget: " + i.toString(),
),
),
),
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List Wheel"),
),
body: ListWheelScrollView(
controller: scrollController,
itemExtent: 250,
physics: const FixedExtentScrollPhysics(),
squeeze: 0.9,
children: [
buildCard(0),
buildCard(1),
buildCard(2),
buildCard(3),
buildCard(4),
buildCard(5),
buildCard(6),
buildCard(7),
buildCard(8),
buildCard(9),
buildCard(10),
buildCard(11),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
scrollController.animateToItem(9,
duration: const Duration(seconds: 1), curve: Curves.easeInOut);
},
child: const Icon(Icons.ac_unit),
),
);
}
}
我正在尝试 select/scroll 在单击按钮时自动转到 ListWheelScrollView 中的特定元素。它适用于当前页面中显示的元素。但是我一直遇到由于延迟加载导致列表超出屏幕的问题。
由于 ListWheelScrollView 中的小部件未呈现,当尝试滚动到屏幕之外时会为当前上下文抛出 null 错误。
我尝试过的:
尝试 1:我尝试将 ListWheelScrollView 包装在 SingleChildScrollView 小部件中。没有解决问题。
尝试 2:尝试使用 (scrollable_positioned_list )。它用于 ListView 而不是 ListWheelScrollView。
这是我的源代码。
import 'package:flutter/material.dart';
// import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
void main() {
runApp(
const MaterialApp(home: StatefulWidgetsExample()), // use MaterialApp
);
}
class StatefulWidgetsExample extends StatefulWidget {
const StatefulWidgetsExample({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _StatefulWidgetsExampleState();
}
class _StatefulWidgetsExampleState extends State<StatefulWidgetsExample> {
final itemKey = GlobalKey();
final scrollController = ScrollController();
Future animateTo() async {
BuildContext? context = itemKey.currentContext;
scrollController.position.ensureVisible(
itemKey.currentContext!.findRenderObject()!,
duration: const Duration(seconds: 1),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List Wheel"),
),
body: Column(
children: [
Expanded(
child: Center(
child: Row(
children: [
SizedBox(
height: 500,
width: 200,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
height: 500,
width: 200,
child: ListWheelScrollView(
controller: scrollController,
itemExtent: 100,
children: <Widget>[
const MaterialButton(
onPressed: null,
child: Text(
"Item 1",
textAlign: TextAlign.start,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 2",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 3",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 4",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
Container(
alignment: Alignment.center,
key: itemKey,
child: const MaterialButton(
onPressed: null,
child: Text(
"Item 5",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 6",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 7",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
const MaterialButton(
onPressed: null,
child: Text(
"Item 8",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25),
),
),
],
clipBehavior: Clip.hardEdge,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: MaterialButton(
color: Colors.red,
onPressed: animateTo,
child: const Text("Animate to"),
),
),
],
),
),
),
],
),
);
}
}
任何 help/suggestion 将不胜感激。谢谢!
在做了一些基础工作后,我发现可以通过 FixedExtentScrollController
来完成。
如果有人面临同样的问题,这里是完整的例子。
void main() {
runApp(
const MaterialApp(home: StatefulWidgetsExample()), // use MaterialApp
);
}
class StatefulWidgetsExample extends StatefulWidget {
const StatefulWidgetsExample({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _StatefulWidgetsExampleState();
}
class _StatefulWidgetsExampleState extends State<StatefulWidgetsExample> {
final FixedExtentScrollController scrollController =
FixedExtentScrollController();
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
Widget buildCard(int i) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 200,
height: 200,
color: Colors.red,
child: Center(
child: Text(
"Widget: " + i.toString(),
),
),
),
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List Wheel"),
),
body: ListWheelScrollView(
controller: scrollController,
itemExtent: 250,
physics: const FixedExtentScrollPhysics(),
squeeze: 0.9,
children: [
buildCard(0),
buildCard(1),
buildCard(2),
buildCard(3),
buildCard(4),
buildCard(5),
buildCard(6),
buildCard(7),
buildCard(8),
buildCard(9),
buildCard(10),
buildCard(11),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
scrollController.animateToItem(9,
duration: const Duration(seconds: 1), curve: Curves.easeInOut);
},
child: const Icon(Icons.ac_unit),
),
);
}
}