Flutter 在可滚动列中与其他小部件一起颤振ListView.Builder()
我有一个TabBarView(),其中包含大量不同的视图。我希望它们中有一个列,顶部有一个TextField,下面有一个ListView.Builder(),但这两个小部件应该位于同一个可滚动区域(scrollview)。我实现它的方式引发了一些错误:Flutter 在可滚动列中与其他小部件一起颤振ListView.Builder(),flutter,dart,flutter-layout,Flutter,Dart,Flutter Layout,我有一个TabBarView(),其中包含大量不同的视图。我希望它们中有一个列,顶部有一个TextField,下面有一个ListView.Builder(),但这两个小部件应该位于同一个可滚动区域(scrollview)。我实现它的方式引发了一些错误: @override Widget build(BuildContext context) { return new Column( mainAxisAlignment: MainAxisAlignment.center, mainAx
@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: new TextField(
decoration: new InputDecoration(
hintText: "Type in here!"
),
)
),
new ListView.builder(
itemCount: _posts.length, itemBuilder: _postBuilder)
],
);
}
我读过关于在扩展区域中堆叠ListView.builder()的文章,但它使文本字段有点“粘性”,这不是我想要的。:-)
我也遇到过CustomScrollView,但不完全理解如何实现它。
列
不可滚动,这就是为什么顶部的文本字段
不会滚动,而底部的列表视图会滚动
在我看来,解决这个问题的最好方法是将文本字段
作为列表视图
中的第一项
因此,您不需要列,您的父窗口小部件是列表视图
,它的子窗口是文本字段
,后面是使用\u postBuilder
构建的剩余项。将列表视图放在扩展的
窗口小部件中可以解决您的问题:
@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: new TextField(
decoration: new InputDecoration(
hintText: "Type in here!"
),
)
),
new Expanded(child: ListView.builder(
itemCount: _posts.length, itemBuilder: _postBuilder))
],
);
}
@覆盖
小部件构建(构建上下文){
返回新列(
mainAxisAlignment:mainAxisAlignment.center,
mainAxisSize:mainAxisSize.max,
儿童:[
新填料(
填充:边缘组。对称(水平:16.0,垂直:8.0),
孩子:新文本字段(
装饰:新的输入装饰(
hintText:“在这里输入!”
),
)
),
新扩展(子项:ListView.builder)(
itemCount:_posts.length,itemBuilder:_postBuilder))
],
);
}
最好的方法是使列可滚动,方法是使SingleChildScrollView的列子级可滚动,然后将相同的ScrollController分配给SingleChildScrollView和ListView.builder。这将使文本字段和下面的列表视图可滚动。错误原因:
列
在主轴方向(纵轴)上扩展到最大大小,列表视图也扩展到最大大小
解决方案
SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
您需要限制列表视图的高度
,以便它能够展开以匹配列
,有几种方法可以解决此问题,我在这里列出了几种方法:
如果要允许列表视图
占用列
中的所有剩余空间,请使用Flexible
Column(
children: <Widget>[
Flexible(
child: ListView(...),
)
],
)
如果您的列表视图
很小,可以尝试对其使用包覆面提取
属性
Column(
children: <Widget>[
ListView(
shrinkWrap: true, // use it
)
],
)
列(
儿童:[
列表视图(
包络处理:true,//使用它
)
],
)
以下是解决方案:
SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
children: <Widget>[
Text('Hey'),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount:18,
itemBuilder: (context,index){
return Text('Some text');
})
],
),
),
class NestedListExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: Text('Header'),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
return ListTile(title:Text('Item $index'));
},
),
),
],
);
}
}
SingleChildScrollView(
物理:物理(),
子:列(
儿童:[
Text('Hey'),
ListView.builder(
物理学:NeverscrollableScroll物理学(),
收缩膜:对,
物品计数:18,
itemBuilder:(上下文,索引){
返回文本(“某些文本”);
})
],
),
),
使用扩展小部件进行约束,而不会溢出这些像素:)
列(
儿童:[
扩大(
子项:ListView(),
),
扩大(
子项:ListView(),
),
],
)
只需在ListView.builder()中添加物理:NeverScrollableScrollPhysics(),这样您就可以滚动添加物理:NeverScrollableScrollPhysics()
内部ListView.builder()
方法,嵌套的ListView
将滚动解决方案
SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
仅占用所需的空间(当有更多项目时仍将滚动)
不允许用户滚动的滚动物理。仅表示列+SingleChildScrollView滚动工作。就我的未来而言,我是这样做的:
SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text("Hey ho let's go!"),
Flexible(
child: FutureBuilder(
future: getData(),
builder: (BuildContext context,
AsyncSnapshot<List<Sale>> snapshot) {
if (snapshot.connectionState != ConnectionState.done ||
snapshot.hasData == null) {
return CircularProgressIndicator();
} else {
data = snapshot.data;
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return dataItemWidget(size, data[index], context);
},
itemCount: data.length,
);
}
},
),
),
],
),
),
SingleChildScrollView(
物理:物理(),
子:列(
mainAxisSize:mainAxisSize.min,
儿童:[
文本(“嘿,我们走吧!”),
灵活的(
孩子:未来建设者(
future:getData(),
生成器:(BuildContext上下文,
异步快照(快照){
如果(snapshot.connectionState!=connectionState.done||
snapshot.hasData==null){
返回循环ProgressIndicator();
}否则{
data=snapshot.data;
返回ListView.builder(
物理学:NeverscrollableScroll物理学(),
收缩膜:对,
itemBuilder:(构建上下文,int索引){
返回dataItemWidget(大小、数据[索引]、上下文);
},
itemCount:data.length,
);
}
},
),
),
],
),
),
使用物理:NeverScrollableScrollPhysics()和收缩包装:true内置ListView.Builder()并享受以下是一个有效的解决方案:
SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
children: <Widget>[
Text('Hey'),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount:18,
itemBuilder: (context,index){
return Text('Some text');
})
],
),
),
class NestedListExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: Text('Header'),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
return ListTile(title:Text('Item $index'));
},
),
),
],
);
}
}
这是一个在dartpad上的
您可以对其他子级使用SliverToBoxAdapter,因为只有Sliver可以是CustomScrollView的直接子级
如果所有列表项的高度都相同,则可以使用,这会更有效,因为每个子项的高度不是动态计算的,但您必须知道确切的像素高度。您还可以使用a,其中您提供了列表中的第一项(原型),所有其他子项将使用原型的高度,因此您不需要知道以像素为单位的确切高度
//If you want Listview.builder inside ListView and want to scroll the parent ListView// //whenever the Items in ListView.builder ends or start you can do it like this
body: ListView(
physics: ScrollPhysics(),
children: [
SizedBox(height: 20),
Container( height: 110.0 *5, // *5 to give size to the container //according to items in the ListView.builder. Otherwise will give hasSize Error
child:ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: 5,
itemBuilder: (BuildContext context, int indexChild) {
return InkWell(child:Container(height:100));}))
),]),
返回列(
儿童:[
文本(“流行类别”),
扩展(
子项:ListView.bu
class NestedListExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: Text('Header'),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
return ListTile(title:Text('Item $index'));
},
),
),
],
);
}
}
//If you want Listview.builder inside ListView and want to scroll the parent ListView// //whenever the Items in ListView.builder ends or start you can do it like this
body: ListView(
physics: ScrollPhysics(),
children: [
SizedBox(height: 20),
Container( height: 110.0 *5, // *5 to give size to the container //according to items in the ListView.builder. Otherwise will give hasSize Error
child:ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: 5,
itemBuilder: (BuildContext context, int indexChild) {
return InkWell(child:Container(height:100));}))
),]),
Column(
mainAxisSize: MainAxisSize.max, //Add this line onyour column
children:[
SomeWidget(),
Expanded(child:ListView.builder())
]
)