颤振:ListView不可滚动,不可反弹
我有以下示例(在iPhone X、iOS 11上测试):颤振:ListView不可滚动,不可反弹,listview,dart,scrollview,flutter,Listview,Dart,Scrollview,Flutter,我有以下示例(在iPhone X、iOS 11上测试): 导入“包装:颤振/材料.省道”; void main()=>runApp(新的MyApp()); 类MyApp扩展了无状态小部件{ @凌驾 小部件构建(构建上下文){ 返回新材料PP( 标题:“颤振演示”, 主题:新主题数据( 主样本:颜色。蓝色, ), 主页:新MyHomePage(标题:“颤振演示主页”), ); } } 类MyHomePage扩展StatefulWidget{ MyHomePage({Key,this.title})
导入“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
@凌驾
小部件构建(构建上下文){
返回新的ListView(
儿童:[
新容器(
身高:40.0,
颜色:颜色,蓝色,
),
新容器(
身高:40.0,
颜色:颜色,红色,
),
新容器(
身高:40.0,
颜色:颜色。绿色,
),
]
);
}
}
在这种情况下,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,
),
]
);
}
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
ScrollController _controller=新的ScrollController();
@凌驾
小部件构建(构建上下文){
返回新的ListView(
控制器:_控制器,
儿童:[
新容器(
身高:40.0,
颜色:颜色,蓝色,
),
新容器(
身高:40.0,
颜色:颜色,红色,
),
新容器(
身高:40.0,
颜色:颜色。绿色,
),
]
);
}
}
在这种情况下,滚动不再可能。为什么当我添加一个ScrollController时,滚动就不可能了?另外,将physics:new BouncingScrollPhysics(),
添加到列表视图也没有帮助
感谢您的帮助:)我找到了一个解决方案,如何使用内容高度小于视口的列表跟踪偏移。在
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;
}
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
ScrollController _controller=新的ScrollController();
@凌驾
小部件构建(构建上下文){
返回新的NotificationListener(
onNotification:_handleScrollPosition,
子项:新自定义滚动视图(
条子:[
新名单(
委托:新建SliverChildListDelegate([
新容器(
身高:40.0,
颜色:颜色,蓝色,
),
新容器(
身高:40.0,
颜色:颜色,红色,
),
新容器(
身高:40.0,
颜色:颜色。绿色,
),
])
)
]
)
);
}
bool_handleScrollPosition(滚动通知){
打印(通知、度量、像素);
返回true;
}
}
只要没有只使用
ScrollController
的解决方案(或“更好的”(更优雅的))解决方案,我就接受这个答案。要始终在列表视图上启用滚动,可以使用AlwaysScrollableScrollPhysics
类包装您想要的原始滚动物理。更多细节。如果需要,可以指定父级或依赖默认值
以下是添加选项的示例:
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,
),
]
);
}
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
ScrollController _controller=新的ScrollController();
@凌驾
小部件构建(构建上下文){
返回新的ListView(
物理:常量AlwaysScrollablePhysics(),//新建
控制器:_控制器,
儿童:[
新容器(
身高:40.0,
颜色:颜色,蓝色,
),
新容器(
身高:40.0,
有限公司
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,
),
]
);
}
}
Widget noti = new NotificationListener(
child:listView,
onNotification: (ScrollNotification note){
print(note.metrics.pixels.toInt());
},
);
ListView(
physics: const AlwaysScrollableScrollPhysics(),
children : [...]
}
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(),
);
Container(
width: 400,
child: Drawer(
child: Stack(children: [
Container(
height: MediaQuery.of(context).size.height-80,
child: ListView(
controller: controller,
padding: EdgeInsets.zero,
physics: AlwaysScrollableScrollPhysics(),
children: [
Container(
height: 300,
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
child: DrawerHeader(
child:Stack(children: [
Center(
child: Column(
children: [
nullCatcher(image) == "" ? Image.asset("assets/images/doctor.png",height: 90,width: 90,) : Image.network(
"$image",
height: 90,
width: 90,
),
SizedBox(width: 30,),
Text("$name",style: TextStyle(color: Colors.grey[700],fontWeight: FontWeight.bold,fontSize: 25),),
Text("$specialty",style: TextStyle(color: Colors.grey[600]),),
],
),
),
Positioned(
right: 0,bottom: 10,
child: Text("Version: 1.0.0",style: TextStyle(color: Colors.orange),))
],),
),
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Container(
height: 70,
padding: EdgeInsets.symmetric(horizontal: 30),
decoration: drawerListDecoration,
child: Row(
children: [
Container(
height: 35,width: 35,
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.circular(100)
),
child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
SizedBox(width: 20,),
Text('Create Appointment'),
],
)),
onTap: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>CreateAppointment()));
// Update the state of the app.
// ...
},
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Container(
height: 70,
padding: EdgeInsets.symmetric(horizontal: 30),
decoration: drawerListDecoration,
child: Row(
children: [
Container(
height: 35,width: 35,
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.circular(100)
),
child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
SizedBox(width: 20,),
Text('Appointment / Prescription List'),
],
)),
onTap: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
// Navigator.pop(context);
},
),
Container(
height: 70,
padding: EdgeInsets.symmetric(horizontal: 30 ),
color: Colors.grey[200],
child: Row(
children: [
Container(
height: 35,width: 35,
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.circular(100)
),
child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
SizedBox(width: 20,),
Text("Clinical Options:",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.grey[600]),),
],
),
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Container(
height: childHeight,
padding: EdgeInsets.only(left: childPaddeing),
// decoration: drawerListDecoration,
child: Row(
children: [
lineDesign(),
SizedBox(width: 20,),
Text('Chief Complain'),
],
)),
onTap: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
// Navigator.pop(context);
},
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Container(
height: 50,
padding: EdgeInsets.symmetric(horizontal: 45),
decoration: drawerListDecoration,
child: Row(
children: [
lineDesign(),
SizedBox(width: 20,),
Text('On Examination'),
],
)),
onTap: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
// Navigator.pop(context);
},
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Container(
height: 70,
padding: EdgeInsets.symmetric(horizontal: 30),
decoration: drawerListDecoration,
child: Row(
children: [
Container(
height: 35,width: 35,
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.circular(100)
),
child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
SizedBox(width: 20,),
Text('Examination Category'),
],
)),
onTap: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
// Navigator.pop(context);
},
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Container(
height: 70,
padding: EdgeInsets.symmetric(horizontal: 30),
decoration: drawerListDecoration,
child: Row(
children: [
Container(
height: 35,width: 35,
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.circular(100)
),
child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
SizedBox(width: 20,),
Text('Diagnosis'),
],
)),
onTap: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
// Navigator.pop(context);
},
),
ListTile(
contentPadding: EdgeInsets.zero,
title: Container(
height: 70,
padding: EdgeInsets.symmetric(horizontal: 30),
decoration: drawerListDecoration,
child: Row(
children: [
Container(
height: 35,width: 35,
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.circular(100)
),
child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
SizedBox(width: 20,),
Text('Investigations'),
],
)),
onTap: () {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
// Navigator.pop(context);
},
),
],
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: ButtonTheme(
child: RaisedButton(
color: Colors.red[900],
onPressed: (){
if(blocState is LogoutInLoading){}else logoutAlert(blocContext);
},
child: Container(
height: 70,
child:blocState is LogoutInLoading ? Container( height: 20,width: 20,margin: EdgeInsets.symmetric(vertical: 25), child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(Colors.white),),) : Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Sign Out",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 25),),
SizedBox(width: 20,),
Icon(Icons.logout,color: Colors.white,)
],
),
),
),
)
)
],),
),
);