flutter - Flutter:调用setState时ListView滚动回原点
问题描述
我有一个带有一堆图标的水平 ListView。当用户单击图标时,我会调用setState
以跟踪所选项目的索引(因此我可以突出显示它)。
问题是,无论何时选择一个项目,ListView 都会滚动回到开头(参见下面的 GIF):
这是代码:
class _FormScreenState extends State<FormScreen> {
int selectedCategory = 0;
final categories = [
{'icon': Icons.shopping_basket, 'category': 'Shopping'},
{'icon': Icons.local_cafe, 'category': 'Eating out'},
// ....
];
Widget build(BuildContext context) {
final _formKey = GlobalKey<FormState>();
return Form(
key: _formKey,
child: SafeArea(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: <Widget>[
SizedBox(height: 40.0),
Text('Some money disappeared ',
style: TextStyle(fontSize: 24.0)),
SizedBox(height: 40.0),
TextFormField(
autofocus: true,
controller: _ctrlTxtAmount,
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: 'AED ...',
),
focusNode: fcsNodeTxtAmount,
style: TextStyle(fontSize: 22),
validator: (value) {
if (value.isEmpty || double.tryParse(value) == null) {
return "Amount needs to be a number";
}
return null;
},
),
SizedBox(height: 30.0),
Container(
height: 70.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: const EdgeInsets.all(12.0),
child: GestureDetector(
onTap: () {
setState(() {
selectedCategory = index;
});
},
child: Icon(categories[index]['icon'],
size: 40.0,
color: selectedCategory == index
? Colors.purple
: Colors.grey),
));
},
),
),
SizedBox(
height: 20.0,
),
TextField(
controller: _ctrlTxtDescription,
decoration: InputDecoration(
hintText: 'What was it for?',
),
style: TextStyle(fontSize: 22),
),
SizedBox(
height: 20.0,
),
FlatButton(
onPressed: () {
if (_formKey.currentState.validate()) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(
'Hang on a sec..',
style: TextStyle(fontSize: 22),
)));
// Submit to server
_submitGoogleForm().then((isSuccess) {
// Report result
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(
isSuccess ? 'Success' : 'Failed',
style: TextStyle(fontSize: 22),
)));
// Hide Snackbar in use (if present)
Scaffold.of(context).hideCurrentSnackBar();
if (isSuccess) {
_clearForm();
// Focus on Amount
FocusScope.of(context).requestFocus(fcsNodeTxtAmount);
}
});
}
},
color: Colors.purple,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Log it',
style: TextStyle(fontSize: 22.0, color: Colors.white),
),
))
],
),
),
),
);
}
}
如何防止它向后滚动?
我试过了:
- 添加
physics: ScrollPhysics()
到 ListView(行为没有变化) - 添加
key: ObjectKey(_list.hashCode)
到 ListView(行为没有变化)
解决方案
final _formKey = GlobalKey<FormState>();
从方法中删除build
并将其作为状态变量。
class _FormScreenState extends State<FormScreen> {
final _formKey = GlobalKey<FormState>();
...
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: SafeArea(
child: Container(
...
推荐阅读
- python - 将 datetime.timedelta 添加到数据帧切片 (.loc) 未在数据帧中正确更新
- python - 如何在没有 URL 错误的情况下将绘图嵌入 Bokeh Flask?
- python - Jupyter matplotlib 函数查询
- c - 如何包装要在 Wine 中使用的 Linux 库?我不断收到 BAD_IMAGE_FORMAT
- gis - 关于地图自动创建问题的建议
- ios - 从 xib 视图和 swift 文件创建 tableview 并从另一个文件填充
- java - SymmetricDS 只同步一种方式
- youtube - How to get metrics from YouTube Analytics API for every video which belongs to current user?
- r - Efficient way of labelling based on start and end position
- javascript - 为什么在控制台中两次显示“返回语句后无法访问代码”警告?(火狐 72.0.2,Win 10)