我有以下示例(在iPhone X,iOS 11上测试):
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new ListView(
children: <Widget>[
new Container(
height: 40.0,
color: Colors.blue,
),
new Container(
height: 40.0,
color: Colors.red,
),
new Container(
height: 40.0,
color: Colors.green,
),
]
);
}
}
在这种情况下,ListView的行为与预期的一样。我可以滚动到视口之外,ListView会再次反弹(典型的iOS行为)。但是当我添加ScrollController来跟踪偏移量时,滚动的行为会发生变化:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController _controller = new ScrollController();
@override
Widget build(BuildContext context) {
return new ListView(
controller: _controller,
children: <Widget>[
new Container(
height: 40.0,
color: Colors.blue,
),
new Container(
height: 40.0,
color: Colors.red,
),
new Container(
height: 40.0,
color: Colors.green,
),
]
);
}
}
在这种情况下,滚动不再可能。为什么当我添加ScrollController时,滚动不再可能?将physics: new BouncingScrollPhysics(),
添加到ListView也无济于事。
感谢您的帮助:)
答案 0 :(得分:4)
要始终在ListView
上启用滚动,您可以使用AlwaysScrollableScrollPhysics
类包装所需的原始滚动体。更多细节here。如果需要,您可以指定parent
或依赖默认值。
以下是添加选项的示例:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController _controller = new ScrollController();
@override
Widget build(BuildContext context) {
return new ListView(
physics: const AlwaysScrollableScrollPhysics(), // new
controller: _controller,
children: <Widget>[
new Container(
height: 40.0,
color: Colors.blue,
),
new Container(
height: 40.0,
color: Colors.red,
),
new Container(
height: 40.0,
color: Colors.green,
),
]
);
}
}
答案 1 :(得分:3)
使用AlwaysScrollableScrollPhysics
创建滚动物理学,始终让用户滚动。
对于具有弹跳效果的滚动,只需向滚动条提供物理:BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics)
。即使没有内容溢出,它也将始终可滚动
const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics())
这里是完整的例子
ListView(
padding: EdgeInsets.all(8.0),
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
children: _listData.map((i) {
return ListTile(
title: Text("Item $i"),
);
}).toList(),
);
答案 2 :(得分:2)
只需添加AlwaysScrollableScrollPhysics
ListView(
physics: const AlwaysScrollableScrollPhysics(),
children : [...]
}
答案 3 :(得分:0)
我找到了一个解决方案,如何使用内容高度小于视口的列表来跟踪偏移量。在NotificationListener
方法中使用CustomScrollView
和build()
,如下所示:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController _controller = new ScrollController();
@override
Widget build(BuildContext context) {
return new NotificationListener(
onNotification: _handleScrollPosition,
child: new CustomScrollView(
slivers: [
new SliverList(
delegate: new SliverChildListDelegate([
new Container(
height: 40.0,
color: Colors.blue,
),
new Container(
height: 40.0,
color: Colors.red,
),
new Container(
height: 40.0,
color: Colors.green,
),
])
)
]
)
);
}
bool _handleScrollPosition(ScrollNotification notification) {
print(notification.metrics.pixels);
return true;
}
}
只要没有只有ScrollController
(或更好的&#34;(更优雅))解决方案的解决方案,我会接受这个作为答案。
答案 4 :(得分:0)
我认为如果没有CustomScrollView,此解决方案会更好。只需使用NotificationListener包装ListView。
Widget noti = new NotificationListener(
child:listView,
onNotification: (ScrollNotification note){
print(note.metrics.pixels.toInt());
},
);
我已经测试过,弹跳有效
答案 5 :(得分:0)
**
使用容器高度进行滚动,也可以使用 物理:AlwaysScrollableScrollPhysics(), 控制器:控制器,
**
implementation 'com.google.android.material:material:1.2.1'