Here is my code :
import 'package:all_in_one/cooking/pages/recipe/header/search_bar_header.dart';
import 'package:all_in_one/cooking/pages/recipe/header/welcome_header.dart';
import 'package:flutter/material.dart';
class MyRecipePage extends StatefulWidget {
final String title;
MyRecipePage({Key? key, required this.title}) : super(key: key);
@override
_MyRecipePageState createState() => _MyRecipePageState();
}
class _MyRecipePageState extends State<MyRecipePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
WelcomeHeader(),
SearchBarHeader(),
SliverGrid.count(),
],
) ,
);
}
}
class WelcomeHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
return
SliverPersistentHeader(
floating: true,
delegate: SliverAppBarDelegate(
minHeight: 0,
maxHeight: 100,
child: Container(
color: Colors.white,
child: _MyWelcomingHeader(),
),
),
);
}
}
class _MyWelcomingHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Flexible(
child: CircleAvatar(
radius: 57,
backgroundColor: Colors.grey.shade50,
child: Image.asset("assets/emoji-food.jpg"),
),
),
Flexible(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
'Enjoy the recipes',
style: TextStyle(
color: Colors.black,
fontSize: 26.0,
fontWeight: FontWeight.bold,
),
),
),
),
],
);
}
}
class SearchBarHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliverPersistentHeader(
pinned: true,
delegate: SliverAppBarDelegate(
minHeight: 50,
maxHeight: 50,
child: Container(
color: Colors.white,
child: _MySearchBar(),
),
),
);
}
}
class _MySearchBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(width: 10),
const Icon(Icons.search, color: Colors.grey, size: 30),
const SizedBox(width: 5),
Text("Search product",
style: TextStyle(
color: Colors.grey.shade500, fontSize: 12, fontWeight: FontWeight.w200))
],
);
}
}
The code of the silver bar Delegate is from this stackoverflow post
import 'package:flutter/material.dart';
import 'dart:math' as math;
class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
final double minHeight;
final double maxHeight;
final Widget child;
SliverAppBarDelegate({
required this.minHeight,
required this.maxHeight,
required this.child,
});
@override
double get minExtent => minHeight;
@override
double get maxExtent => math.max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return SizedBox.expand(child: child);
}
@override
bool shouldRebuild(SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}
My goal is to have 2 SliverPersistentHeader
, one pinned and one floating.
The one floating (the 1st one) should resize the text and the image while scrolling..
In the following screenshot, we can see that the 2nd SliverPersistentHeader
is overlapping the 1st one.
How can I do to make the Text
resize itself. I try to use Flexible
like I did for the CircleAvatar
but I can't succeed :/
Thanks
I found a solution using the opacity, so my WelcomeHeader
becomes :
import 'package:flutter/material.dart';
import 'dart:math' as math;
class WelcomeHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliverAppBar(
backgroundColor: Colors.white,
pinned: false,
floating: false,
snap: false,
expandedHeight: 120,
flexibleSpace: _MyWelcomingHeader()
);
}
}
class _MyWelcomingHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, c) {
final settings = context
.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
final deltaExtent = settings!.maxExtent - settings.minExtent;
final t =
(1.0 - (settings.currentExtent - settings.minExtent) / deltaExtent)
.clamp(0.0, 1.0);
final fadeStart = math.max(0.0, 1.0 - kToolbarHeight / deltaExtent);
const fadeEnd = 1.0;
final opacity = 1.0 - Interval(fadeStart, fadeEnd).transform(t);
return Padding(
padding: const EdgeInsets.all(8.0),
child: Opacity(
opacity: opacity,
child: Column(
children: [
Flexible(
child: CircleAvatar(
radius: 57,
backgroundColor: Colors.grey.shade50,
child: Image.asset("assets/emoji-food.jpg"),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Enjoy the recipes !',
style: TextStyle(
color: Colors.black,
fontSize: 26.0,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
);
});
}
}