I have a problem with a SizeTransition
that is within a SliverFillRemaining
. The issue is that the SliverFillRemaining
does not adjust its size proportionally to the height of the SizeTransition
. Even when the sizeFactor of the SizeTransition
is 0, the SliverFillRemaining
still occupies the space it would when the SizeTransition
's sizeFactor is 1. I expected SliverFillRemaining
to only fill the remaining space in the viewport but in the sample code below it uses more space than necessary. This is not an issue with SingleChildScrollView
for which I've provided sample code as well.
Code with SliverFillRemaining showing too much space being taken up:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: const CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
children: [
SizeTransitionExample(),
SizeTransitionExample(),
SizeTransitionExample(),
SafeArea(child: Text("Text")),
],
),
),
],
),
),
);
}
}
class SizeTransitionExample extends StatefulWidget {
const SizeTransitionExample({super.key});
@override
State<SizeTransitionExample> createState() => _SizeTransitionExampleState();
}
class _SizeTransitionExampleState extends State<SizeTransitionExample> with TickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
)..repeat(reverse: true);
late final Animation<double> _animation = CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final pageHeight = MediaQuery.sizeOf(context).height;
return SizeTransition(
sizeFactor: _animation,
child: Center(
child: FlutterLogo(size: pageHeight / 3),
),
);
}
}
Code with SingleChildScrollView with the expected behavior:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: const SingleChildScrollView(
child: ColoredBox(
color: Colors.amber,
child: Column(
children: [
SizeTransitionExample(),
SizeTransitionExample(),
SizeTransitionExample(),
SafeArea(child: Text("Text")),
],
),
),
),
),
);
}
}
class SizeTransitionExample extends StatefulWidget {
const SizeTransitionExample({super.key});
@override
State<SizeTransitionExample> createState() => _SizeTransitionExampleState();
}
class _SizeTransitionExampleState extends State<SizeTransitionExample> with TickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
)..repeat(reverse: true);
late final Animation<double> _animation = CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final pageHeight = MediaQuery.sizeOf(context).height;
return SizeTransition(
sizeFactor: _animation,
child: Center(
child: FlutterLogo(size: pageHeight / 3),
),
);
}
}