前两天在flutter中学习了sliver widget的使用,正在玩着它来增长自己的技能。我正在构建一种想象中的项目,但我在那里遇到了问题。
让我们想想,在 x 小部件下的身体容器中有 15 个容器,它们允许它们垂直滚动。现在,我的目标是,当我滚动时,我希望当容器编号 5 到达顶部时,容器编号 5会像 appbar 或 sliver appbar 一样卡在那里,其他人会在它下面滚动。
在这里,我在 CustomScrollView 小部件下使用 sliver 和 SliverFixedExtentList 来了解我的目标,如果还有其他没有 sliver 的选项,请随时与我分享。提前致谢:)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
actions: <Widget>[
Icon(
Icons.camera_front,
size: 40,
)
],
title: Text("Sliver Example"),
leading: Icon(Icons.menu),
backgroundColor: Colors.green,
expandedHeight: 100.0,
floating: true,
pinned: true),
SliverFixedExtentList(
itemExtent: 75,
delegate: SliverChildListDelegate([
Container(
color: Colors.blue,
child: Text("1"),
),
Container(
color: Colors.pink,
child: Text("2"),
),
Container(
color: Colors.yellow,
child: Text("3"),
),
Container(
color: Colors.red,
child: Text("4"),
),
Container(
color: Colors.black,
child: Text(
"Desired Appbar Conainer number 5, which will stuck\n there instead of the sliverappbar sliver example when it reached to the top ",
style: TextStyle(color: Colors.white),
),
),
Container(
color: Colors.amber,
child: Text("6"),
),
Container(
color: Colors.blue,
child: Text("7"),
),
Container(
color: Colors.yellow,
child: Text("8"),
),
Container(
color: Colors.blue,
child: Text("9"),
),
Container(
color: Colors.pink,
child: Text("10"),
),
Container(
color: Colors.blue,
child: Text("11"),
),
Container(
color: Colors.yellow,
child: Text("12"),
),
Container(
color: Colors.blue,
child: Text("13"),
),
Container(
color: Colors.purpleAccent,
child: Text("14"),
),
Container(
color: Colors.white,
child: Text("15"),
),
]),
),
],
),
),
);
}
}
答案 0 :(得分:1)
你的想法仍然有效,只需要一点点调整,而不是使用 SliverFixedExtentList,你可以使用这个,flutter_sticky_header,它提供粘性 sliver 列表标题,对于你的情况,你可以只设置一个标题:< /p>
import 'package:flutter/material.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';
import '../common.dart';
class ListExample extends StatelessWidget {
const ListExample({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
//SliverAppBar(),
//SliverList(),
_StickyHeaderList(index: 2),
//SliverList(),
],
);
}
}
class _StickyHeaderList extends StatelessWidget {
const _StickyHeaderList({
Key key,
this.index,
}) : super(key: key);
final int index;
@override
Widget build(BuildContext context) {
return SliverStickyHeader(
header: Header(index: index),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) => ListTile(
leading: CircleAvatar(
child: Text('$index'),
),
title: Text('List tile #$i'),
),
childCount: 6,
),
),
);
}
}
答案 1 :(得分:1)
似乎我找到了这个问题的有效解决方案。答案是基于 => this post
这是我解决问题的代码 -
import 'package:flutter/material.dart';
import 'dart:math' as math;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
SliverPersistentHeader makeHeader(String headerText) {
return SliverPersistentHeader(
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 75.0,
maxHeight: 75.0,
child: Container(
color: Colors.black,
child: Center(
child: Text(
headerText,
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverFixedExtentList(
itemExtent: 75,
delegate: SliverChildListDelegate([
Container(
color: Colors.blue,
child: Text("1"),
),
Container(
color: Colors.pink,
child: Text("2"),
),
Container(
color: Colors.yellow,
child: Text("3"),
),
Container(
color: Colors.red,
child: Text("4"),
),
]),
),
makeHeader("Container Number 5"),
SliverFixedExtentList(
itemExtent: 75,
delegate: SliverChildListDelegate([
Container(
color: Colors.amber,
child: Text("6"),
),
Container(
color: Colors.blue,
child: Text("7"),
),
Container(
color: Colors.yellow,
child: Text("8"),
),
Container(
color: Colors.blue,
child: Text("9"),
),
Container(
color: Colors.pink,
child: Text("10"),
),
Container(
color: Colors.blue,
child: Text("11"),
),
Container(
color: Colors.yellow,
child: Text("12"),
),
Container(
color: Colors.blue,
child: Text("13"),
),
Container(
color: Colors.purpleAccent,
child: Text("14"),
),
Container(
color: Colors.white,
child: Text("15"),
),
Container(
color: Colors.yellow,
child: Text("12"),
),
Container(
color: Colors.blue,
child: Text("13"),
),
Container(
color: Colors.purpleAccent,
child: Text("14"),
),
Container(
color: Colors.white,
child: Text("15"),
),
Container(
color: Colors.yellow,
child: Text("12"),
),
Container(
color: Colors.blue,
child: Text("13"),
),
Container(
color: Colors.purpleAccent,
child: Text("14"),
),
Container(
color: Colors.white,
child: Text("15"),
),
Container(
color: Colors.yellow,
child: Text("12"),
),
Container(
color: Colors.blue,
child: Text("13"),
),
Container(
color: Colors.purpleAccent,
child: Text("14"),
),
Container(
color: Colors.white,
child: Text("15"),
),
]),
),
],
),
),
);
}
}
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;
}
}
希望这能帮助像我这样的人:)