我是Flutter的新学习者。现在,我必须为一个项目实现一个UI(Link)。我认为我应该使用 CustomerScrollView 或 NestedScrollView 完成它。我已经尽力了,但是我很讨厌实现标头 SliverAppBar 和 ADBar 。有人可以帮忙提出一些建议吗?
我尝试使用NestedScrollView,并将所有项目放入SliverAppBar,遇到一个问题。如果我使用FlexibleSpaceBar,则在初始化时所有项目都将缩小到手机之外,直到向上滚动一段距离,您什么都看不到。如果我放弃FlexibleSpaceBar并使用普通的Widget,那似乎还可以,但是如果我向上滚动并一旦 Ad Bar 与文本项重叠,则错误“ BOTTOM OVERFLOWED XX PIXELS”将消失。 >
class _MyPageState extends State<MyPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appbar: AppBar(/*build my AppBar*/),
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
...,
expandedHeight: 180,
flexibleSpace: FlexibleSpaceBar( //if use, all texts are out of phone when initializing
//if not use, Error('BOTTOM OVERFLOWED xx PIXELS') while scrolling up
title: Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('Text 1'),
Text('Text 2'),
Text('Text 3'),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('Text 4'),
Text('Text 5'),
Text('Text 6'),
],
),
],
)
),
),
//implement AD Bar
SliverPersistentHeader(
delegate: _SliverPersistentHeaderDelegate(_buildADBar())
),
)
];
},
body: //build body
GridView.count(
crossAxisCount: 2,
children: ...
),
),
);
}
}
答案 0 :(得分:0)
作为选择
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('App Bar'),
centerTitle: true,
elevation: 0,
),
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 180,
floating: false,
elevation: 0,
backgroundColor: Colors.green,
flexibleSpace: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('Text 1'),
Text('Text 2'),
Text('Text 3'),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text('Text 4'),
Text('Text 5'),
Text('Text 6'),
],
),
],
),
),
),
),
SliverAppBar(
pinned: true,
elevation: 0,
flexibleSpace: Container(
alignment: Alignment.center,
height: kToolbarHeight,
color: Colors.redAccent,
child: Text('AD Bar'),
),
),
SliverGrid.count(
crossAxisCount: 2,
children: List.generate(20, (index) {
return Card(
color: Colors.white,
);
}),
),
],
),
),
);
}
}
答案 1 :(得分:0)
这是您需要做的:
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Collapsing List Demo')),
body: CollapsingList(),
),
);
}
}
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
@required this.minHeight,
@required this.maxHeight,
@required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
@override
double get minExtent => minHeight;
@override
double get maxExtent => math.max(maxHeight, minHeight);
@override
Widget build(
BuildContext context,
double shrinkOffset,
bool overlapsContent)
{
return new SizedBox.expand(child: child);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
class CollapsingList extends StatelessWidget {
SliverPersistentHeader makeHeader(String headerText) {
return SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 60.0,
maxHeight: 200.0,
child: Container(
color: Colors.lightBlue, child: Center(child:
Text(headerText))),
),
);
}
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
makeHeader('Header Section 1'),
SliverGrid.count(
crossAxisCount: 3,
children: [
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
Container(color: Colors.orange, height: 150.0),
Container(color: Colors.yellow, height: 150.0),
Container(color: Colors.pink, height: 150.0),
Container(color: Colors.cyan, height: 150.0),
Container(color: Colors.indigo, height: 150.0),
Container(color: Colors.blue, height: 150.0),
],
),
makeHeader('Header Section 2'),
SliverFixedExtentList(
itemExtent: 150.0,
delegate: SliverChildListDelegate(
[
Container(color: Colors.red),
Container(color: Colors.purple),
Container(color: Colors.green),
Container(color: Colors.orange),
Container(color: Colors.yellow),
],
),
),
makeHeader('Header Section 3'),
SliverGrid(
gridDelegate:
new SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Container(
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: new Text('grid item $index'),
);
},
childCount: 20,
),
),
makeHeader('Header Section 4'),
// Yes, this could also be a SliverFixedExtentList. Writing
// this way just for an example of SliverList construction.
SliverList(
delegate: SliverChildListDelegate(
[
Container(color: Colors.pink, height: 150.0),
Container(color: Colors.cyan, height: 150.0),
Container(color: Colors.indigo, height: 150.0),
Container(color: Colors.blue, height: 150.0),
],
),
),
],
);
}
}
我绝对会建议您阅读此Slivers Demystified
希望这会有所帮助。