Flutter - Unwanted padding below SliverAppBar - flutter

How do I remove the space below a SliverAppBar above the body? I know it is the SliverAppBar causing the space because the padding only gets removed when I remove that:
Widget buildScrollable(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverPadding(
padding: EdgeInsets.zero,
sliver: SliverAppBar(
toolbarHeight: widget.toolbarHeight ?? _appBarHeight,
systemOverlayStyle: SystemUiOverlayStyle.dark,
brightness: Brightness.light,
actions: [
Container(
width: widget.leadingWidth ?? APP_BAR_LEADING_WIDTH,
)
],
leading: Padding(
padding: const EdgeInsets.only(left: STANDARD_PAD),
child: widget.leading),
leadingWidth: widget.leadingWidth ?? APP_BAR_LEADING_WIDTH,
centerTitle: true,
title: BlMeasureSize(
onChange: (size) {
setState(() {
_appBarHeightOrNull =
size.height < APP_BAR_MIN_HEIGHT
? APP_BAR_MIN_HEIGHT
: size.height;
});
},
child: widget.title),
pinned: false,
stretch: true,
flexibleSpace: FlexibleSpaceBarSettings(
toolbarOpacity: 1,
currentExtent: _appBarHeight,
maxExtent: _appBarHeight,
minExtent: _appBarHeight,
child: FlexibleSpaceBar(
background: Container(
decoration: const BoxDecoration(
gradient: edenYellowGradient,
),
))),
bottom: widget.bottom,
))
];
},
physics: ClampingScrollPhysics(),
body: Builder(
builder: ((context) {
_scrollController.addListener(_scrollListener);
return Stack(children: [
SlideTransition(
position: _offsetAnimation,
child: Container(
height: _appBarHeight,
decoration: const BoxDecoration(
gradient: edenYellowGradient,
),
)),
SafeArea(child: widget.body)
]);
}),
)),
);
}
I've tried SliverPadding, ClampingScrollPhysics and PreferredSize. I can't do MediaQuery.removePadding because it disables the SafeArea.

Related

Flutter - How to scroll Container over another

I'm begginning Flutter and I'm searching to scroll ListView over a Container like below
You can use DraggableScrollableSheet
DraggableScrollableSheet(
builder: (context, scrollController) {
return SingleChildScrollView(
controller: scrollController,
child: Column(
children: [],
),
);
},
)
You can follow the doc example
A complete widget
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
openDraggable(context) {
showModalBottomSheet(
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(22),
topRight: Radius.circular(22),
)),
context: context,
builder: (context) => DraggableScrollableSheet(
maxChildSize: 1,
initialChildSize: .4,
expand: false,
builder: (context, scrollController) {
return SingleChildScrollView(
controller: scrollController,
child: Column(
children: [
for (int i = 0; i < 32; i++)
ListTile(
title: Text("item"),
),
],
),
);
},
));
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
openDraggable(context);
},
child: Text("open"),
)
],
),
),
);
}
}
Don't use DraggableScrollableSheet. instead of that widget use the sliver widget, this widget is amazing,
you can use this article and this
CustomScrollView(
slivers: <Widget>[
// appbar of search page
SliverAppBar(
// icon in top left
leading: _icon(context),
// backgroun of appbar
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
// style of app bar
pinned: true,
floating: true,
snap: true,
expandedHeight: 130,
// obtional filter for product
flexibleSpace: FlexibleSpaceBar(
background: Padding(
padding: const EdgeInsets.only(top: 80.0),
child: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(8.0),
padding: const EdgeInsets.symmetric(horizontal: 10.0),
decoration: BoxDecoration(
borderRadius: borderRadius_30,
color: Theme.of(context).primaryColorLight),
child: TextField(
onChanged: (value) {
// you can sort data for user in this section
},
style: TextStyle(
color: Theme.of(context).textSelectionColor,
),
decoration: InputDecoration(
border: InputBorder.none,
// styel of labeltext in textfield
labelStyle: TextStyle(
color: Colors.cyan,
),
labelText: Strings.search,
),
),
),
),
),
),
// body
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return SearchBody(index);
},
childCount: fakeData.length,
),
// number of object
)
],
),
You can use the sliver package, something like this.

How to scroll with NestedScrollView to use stack Circle Avatar over SliverAppBar?

I am dealing with a Flutter project recently and I have such a problem.
See photo 1: here's my code: the photo and text should be between the TabBar widget and the red background like in design (blue).
Here you can see my actual code:
class Main
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
PortfolioSliverAppBar(_pages[_tabController.index].item1),
SliverPersistentHeader(
delegate: SliverPersistentHeaderDelegateImpl(
tabBar: TabBar(
padding: EdgeInsets.only(top: 15.0),
labelColor: Colors.black,
indicatorColor: Colors.black,
indicator: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(18)),
color: Colors.blue),
controller: _tabController,
tabs: _pages
.map<Tab>((Tuple3 page) => Tab(text: page.item1))
.toList(),
),
),
),
];
},
body: Container(
margin: EdgeInsets.only(top: 20.0),
child: TabBarView(
controller: _tabController,
children: _pages.map<Widget>((Tuple3 page) => page.item2).toList(),
),
),
class Silver
class SliverPersistentHeaderDelegateImpl extends SliverPersistentHeaderDelegate {
final TabBar tabBar;
final Color color;
const SliverPersistentHeaderDelegateImpl({
Color color = Colors.transparent,
#required this.tabBar,
}) : this.color = color;
#override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
color: color,
child: tabBar,
);
}
See photo 2: here's the given design:
my view
the actual UI
Thanks a lot!
Please refer to below code
class NestedScrollWithTabs extends StatefulWidget {
const NestedScrollWithTabs({Key key}) : super(key: key);
#override
_NestedScrollWithTabsState createState() => _NestedScrollWithTabsState();
}
class _NestedScrollWithTabsState extends State<NestedScrollWithTabs>
with TickerProviderStateMixin {
var animation;
var controller;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
physics: NeverScrollableScrollPhysics(),
headerSliverBuilder: (headerCtx, innnerBoxIsScrolled) {
if (innnerBoxIsScrolled) {
/* Animation */
controller = AnimationController(
vsync: this,
duration: Duration(
seconds: 1,
),
);
animation = Tween(
begin: 0.0,
end: 1.0,
).animate(controller);
/* Animation */
controller.forward();
}
return <Widget>[
SliverAppBar(
expandedHeight: ScreenUtil().setHeight(185.0),
floating: false,
pinned: true,
backgroundColor: Colors.white,
automaticallyImplyLeading: false,
titleSpacing: 0.0,
centerTitle: true,
elevation: 0.0,
leadingWidth: 0.0,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (innnerBoxIsScrolled != null &&
innnerBoxIsScrolled == true)
FadeTransition(
opacity: animation,
child: Text(
"Title",
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
],
),
flexibleSpace: FlexibleSpaceBar(
background: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Image.network(
"https://images.pexels.com/photos/10181294/pexels-photo-10181294.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" ??
"",
fit: BoxFit.fitWidth,
height: ScreenUtil().setHeight(126.0),
width: ScreenUtil().screenWidth,
filterQuality: FilterQuality.low,
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent loadingProgress) {
if (loadingProgress == null) return child;
return Container(
height: ScreenUtil().setHeight(126.0),
width: ScreenUtil().screenWidth,
color: Colors.grey,
);
},
errorBuilder: (context, error, stackTrace) {
return SizedBox(
height: ScreenUtil().setHeight(126.0),
width: ScreenUtil().screenWidth,
child: Container(
width: ScreenUtil().screenWidth,
),
);
},
),
Positioned(
top: ScreenUtil().setHeight(92.0),
// left: ScreenUtil().setWidth(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CircleAvatar(
backgroundColor: Colors.transparent,
radius: 30.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(
45.0,
),
child: Image.network(
"https://images.pexels.com/photos/10181294/pexels-photo-10181294.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" ??
"",
fit: BoxFit.fill,
height: ScreenUtil().setHeight(72.0),
width: ScreenUtil().screenWidth,
filterQuality: FilterQuality.low,
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent loadingProgress) {
if (loadingProgress == null)
return child;
return Container(
height:
ScreenUtil().setHeight(72.0),
width: ScreenUtil().screenWidth,
color: Colors.grey,
);
},
errorBuilder:
(context, error, stackTrace) {
return SizedBox(
height:
ScreenUtil().setHeight(72.0),
width: ScreenUtil().screenWidth,
child: Container(
width: ScreenUtil().screenWidth,
),
);
},
),
),
),
Text("Name"),
Text("Place"),
],
),
),
],
),
],
),
),
),
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
headerCtx),
sliver: SliverPersistentHeader(
delegate: SliverAppBarDelegate(TabBar(
labelColor: Colors.blue,
unselectedLabelColor: Colors.black,
labelStyle: TextStyle(
fontSize: 15.0,
),
unselectedLabelStyle: TextStyle(
fontSize: 15.0,
),
labelPadding: EdgeInsets.zero,
indicatorColor: Colors.blue,
indicatorPadding: EdgeInsets.zero,
physics: NeverScrollableScrollPhysics(),
tabs: [
Tab(
text: "Tab 1",
),
Tab(
text: "Tab 2",
),
],
)),
pinned: false,
),
),
];
},
body: TabBarView(
children: [
/* Tab 1 */
Container(
color: Colors.white,
child: ListView.builder(
itemCount: 100,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: Text("Index value: $index"),
);
},
),
),
/* Tab 2 */
Container(
color: Colors.white,
child: ListView.builder(
itemCount: 10,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: Text("Index value of Tab 2: $index"),
);
},
),
),
],
),
),
),
),
);
}
}
class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
SliverAppBarDelegate(this.tabBars);
final TabBar tabBars;
#override
double get minExtent => 60.0;
#override
double get maxExtent => 60.0;
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
// shinkOffsetPerValue.value = shrinkOffset;
return new Container(
color: Colors.white,
child: Column(
children: [
tabBars,
],
),
);
}
#override
bool shouldRebuild(SliverAppBarDelegate oldDelegate) {
return false;
}
}

How to move title on Appbar when scrolling

I wanna make flutter app.
How to make a moving title on appbar when scrolloing??
I attached app's status on GIF file.
Where do I need to set moving the title text?
I just make app like Uber app
#override
Widget build(BuildContext context) {
double sliderValue = 0.0;
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: SliverAppBar(
forceElevated: innerBoxIsScrolled ,
backgroundColor: Colors.transparent,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back),
color: Colors.black,
),
elevation: 0.0,
expandedHeight: 100.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
titlePadding: EdgeInsets.only(left: 15.0),
collapseMode: CollapseMode.none,
title: Text("Notification",
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
)),
),
),
),
];
},
body: Center(
child: Text("Sample Text"),
),
),
);
}
Have to use CustomScrollView widget
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('Title'),
pinned: true,
expandedHeight: 48,
),
SliverFillRemaining(
child: Center(
child: Text('sliver'),
)),
],
);

Implementing Collapsing Toolbar in Flutter

I am trying to implement collapsing toolbar in my app using SliverApp bar, but the problem is that the SliverAppBar is overlapping my content when the SliverAppBar is collapsed, I am attaching the gif for more understanding,
the content in the green background is going under the toolbar, I want to avoid that, any leads are appreciated.
#override
Widget build(BuildContext context) {
// TODO: implement buildr
var _tabs = {"1", "2", "3"};
return Scaffold(
backgroundColor: Colors.white,
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: SliverAppBar(
expandedHeight: 250.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
background: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
image: DecorationImage(
fit: BoxFit.fill,
image: CachedNetworkImageProvider(
newsPost.photos[0].url),
),
),
)),
forceElevated: innerBoxIsScrolled,
))
];
},
body: SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
),
SliverPadding(
padding: const EdgeInsets.all(8.0),
sliver: SliverFillRemaining(child: _getBody()),
),
],
);
},
),
)),
);
}
SliverAppBar Creates a material design app bar that can be placed in a NestedScrollView. Both combinly help us in achieving parallax scrolling.
SafeArea(
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 240.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text(
"App Bar",
),
background: Image.network(
"https://images.pexels.com/photos/4148020/pexels-photo-4148020.jpeg",
fit: BoxFit.cover,
)),
),
];
},
body: Center(
child: Text("Hello World!!!"),
),
),
),
);
I think you should use SliverList instead of SliverFillRemaining.
body: SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) {
return CustomScrollView(
shrinkWrap: true,
slivers: <Widget>[
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
),
SliverPadding(
padding: const EdgeInsets.all(0.0),
sliver: SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return Text('Lorem ipsum dolor sit');
}, childCount: 1),
),
),
],
);
},
),
)

Gradient in SliverAppBar (Flutter)?

Has anyone used Gradient in SliverAppBar? I can do it in FlexibleSpace when it's expanded, but when it's collapsed it gets a solid color. Is it possible to treat this?
Wrap a new Container Widget in FlexibleSpaceBar, then add BoxDecoration, LinearGradient under the container.
Unless I'm missing something, this should do what you're asking.
Before it's scrolled it looks like this:
And after scrolling like this:
import 'package:flutter/material.dart';
void main() => runApp(GradientAppBar());
class GradientAppBar extends StatefulWidget {
#override
_GradientAppBarState createState() => _GradientAppBarState();
}
class _GradientAppBarState extends State<GradientAppBar> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
expandedHeight: 100,
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black,
Colors.white,
],
),
),
),
title: Text("This app bar has a gradient!"),
),
SliverList(
delegate: SliverChildListDelegate(
[
Container(
color: Colors.blue,
height: 500,
),
Divider(),
Container(
color: Colors.black12,
height: 500,
),
Divider(),
Container(
color: Colors.lightBlue,
height: 500,
),
Divider(),
Container(
color: Colors.lightGreen,
height: 500,
),
Divider(),
],
),
),
],
),
),
);
}
}
show this from Flutter documention:
CustomScrollView(
slivers: <Widget>[
const SliverAppBar(
pinned: true,
expandedHeight: 250.0,
flexibleSpace: FlexibleSpaceBar(
title: Text('Demo'),
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 20,
),
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: Text('list item $index'),
);
},
),
),
],
)