flutter - Flutter 中的条子是否可以同时具有“扩展”和“收缩”效果?
问题描述
我已经使用,实现了一个屏幕,CustomScrollView
如下所示:SliverAppBar
FlexibleSpaceBar
现在,我试图通过尝试复制以下效果来进一步扩展功能:
这样的事情可以通过使用slivers
in Flutter 来完成吗?
基本上,我希望屏幕打开时图像的初始大小,但根据滚动方向,它应该动画-> 收缩/淡入淡出(保持列表滚动功能)或扩展到全屏(也许到新路线?)。
请帮忙,因为我不确定我应该往哪个方向走。
这是上面屏幕的代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const double bottomNavigationBarHeight = 48;
@override
Widget build(BuildContext context) => MaterialApp(
debugShowCheckedModeBanner: false,
home: SliverPage(),
);
}
class SliverPage extends StatefulWidget {
@override
_SliverPageState createState() => _SliverPageState();
}
class _SliverPageState extends State<SliverPage> {
double appBarHeight = 0.0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
physics: AlwaysScrollableScrollPhysics(),
slivers: <Widget>[
SliverAppBar(
centerTitle: true,
expandedHeight: MediaQuery.of(context).size.height * 0.4,
pinned: true,
flexibleSpace: LayoutBuilder(builder: (context, boxConstraints) {
appBarHeight = boxConstraints.biggest.height;
return FlexibleSpaceBar(
centerTitle: true,
title: AnimatedOpacity(
duration: Duration(milliseconds: 200),
opacity: appBarHeight < 80 + MediaQuery.of(context).padding.top ? 1 : 0,
child: Padding(padding: EdgeInsets.only(bottom: 2), child: Text("TEXT"))),
background: Image.network(
'https://images.pexels.com/photos/443356/pexels-photo-443356.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
fit: BoxFit.cover,
),
);
}),
),
SliverList(delegate: SliverChildListDelegate(_buildList(40))),
],
),
);
}
List _buildList(int count) {
List<Widget> listItems = List();
for (int i = 0; i < count; i++) {
listItems.add(
new Padding(padding: new EdgeInsets.all(20.0), child: new Text('Item ${i.toString()}', style: new TextStyle(fontSize: 25.0))));
}
return listItems;
}
}
解决方案
CustomScrollView
与_SliverPersistentHeader
child: LayoutBuilder(
builder: (context, constraints) {
return CustomScrollView(
controller: ScrollController(initialScrollOffset: constraints.maxHeight * 0.6),
slivers: <Widget>[
SliverPersistentHeader(
pinned: true,
delegate: Delegate(constraints.maxHeight),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, i) => Container(height: 100, color: i.isOdd? Colors.green : Colors.green[700]),
childCount: 12,
),
),
],
);
},
),
使用的Delegate
类SliverPersistentHeader
看起来像:
class Delegate extends SliverPersistentHeaderDelegate {
final double _maxExtent;
Delegate(this._maxExtent);
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
var t = shrinkOffset / maxExtent;
return Material(
elevation: 4,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset('images/bg.jpg', fit: BoxFit.cover,),
Opacity(
opacity: t,
child: Container(
color: Colors.deepPurple,
alignment: Alignment.bottomCenter,
child: Transform.scale(
scale: ui.lerpDouble(16, 1, t),
child: Text('scroll me down',
style: Theme.of(context).textTheme.headline5.copyWith(color: Colors.white)),
),
),
),
],
),
);
}
@override double get maxExtent => _maxExtent;
@override double get minExtent => 64;
@override bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}
推荐阅读
- angularjs - 在圆圈内设置文本样式
- android - ArCore Sceneform:检测图像时播放 .mp4 视频
- ruby - 如何在创建方法中添加记录以加入表?
- angular - 为什么向列标题添加工具提示会导致角度列侧向跳跃?
- java - Java - 等于列表返回假?
- angular - ngSwitch 中的@ViewChild 未定义
- ruby-on-rails - Ruby on Rails/Postgres - 如何为不存在的用户创建新数据库?
- xml - Google 表格中的 XPath
- c# - C# WPF StackPanel 中不需要的间距/图像大小调整
- qt - Qml 地图项偏移