次の例があります(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に追加しても効果がありません。
助けてくれてありがとう:)
ListView
で常にスクロールを有効にするには、AlwaysScrollableScrollPhysics
クラスを使用して、元のスクロールのフィジックスをラップすることができます。詳細 こちら 。必要に応じて、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,
),
]
);
}
}
このソリューションは、CustomScrollViewがなければより良いと思います。 NotificationListenerを使用して、ListViewをラップするだけです。
Widget noti = new NotificationListener(
child:listView,
onNotification: (ScrollNotification note){
print(note.metrics.pixels.toInt());
},
);
私はそれをテストしました、バウンスは効果的です
AlwaysScrollableScrollPhysics
を追加するだけです
ListView(
physics: const AlwaysScrollableScrollPhysics(),
children : [...]
}
ビューポートよりもコンテンツの高さが低いリストでオフセットを追跡する方法を見つけました。次のように、build()
メソッドでNotificationListener
をCustomScrollView
と一緒に使用します。
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
のみ(または「より良い」(よりエレガント)な)解決策がない限り、これを答えとして受け入れます。