Using FutureBuilder with SliverAppBar - flutter

I am newbie and I am still trying to get Widgets and wrapping concept. For me it is probably hardest part of to learn Flutter.
I have Sliver AppBar and I have to get fetch some data and using FutureBuilder. Here is code
#override
Widget build(BuildContext context) => Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
backgroundColor: Colors.red,
expandedHeight: 200,
floating: true,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
'https://source.unsplash.com/random?monochromatic+dark',
fit: BoxFit.cover,
),
title: Text('Flexible Title'),
centerTitle: true,
),
//title: Text('My App Bar'),
leading: Icon(Icons.arrow_back),
actions: [
Icon(Icons.settings),
SizedBox(width: 12),
],
),
],
),
);
}
so my problem is how can I integrate my FutureBuilder snippet to this code.
Here is FutureBuilder:
FutureBuilder<Article>(
future: _futureArticle,
builder: (BuildContext context, AsyncSnapshot<Article> snapshot) {
if (snapshot.hasData) {
final article = snapshot.data?.data;
any help

The correct wrapping:
Widget build(BuildContext context) => Scaffold(
body: FutureBuilder<Article>(
future: _futureArticle,
builder: (BuildContext context, AsyncSnapshot<Article> snapshot) {
if (snapshot.hasData) {
final article = snapshot.data?.data;
return CustomScrollView(
slivers: [
SliverAppBar(
// backgroundColor: Colors.red,
expandedHeight: 200,
floating: true,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(article == null
? 'https://www.tonymacx86.com/attachments/2019-02-05-07-50-43-jpeg.385401/'
: article.imageUrl!),
title: Text('${article!.title}'),
centerTitle: true,
),
leading: const Icon(Icons.arrow_back),
actions: const [
Icon(Icons.settings),
SizedBox(width: 12),
],
),
],
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
);
}

Related

How to make Whatsapp like appbar in flutter

I'm creating an app where I need to implement WhatsApp like AppBar i.e to hide app bar on scroll down and show on reverse.
You can use the SliverAppBar and CustomScrollView to achieve this effect. A sample implementation:
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: false,
snap: false,
floating: false,
expandedHeight: 160.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('AppBar'),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: index.isOdd ? Colors.white : Colors.black12,
height: 100.0,
child: Center(
child: Text('$index', textScaleFactor: 5),
),
);
},
childCount: 50,
),
),
],
),
);
}

How can I put Scroll glow in a sliverList instead of customScrollView?

The glow acts like the entire screen is a list. There some way that I can put the glow below the appbar? (edit: without losing the floating effect of the appbar)
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('Home Scree'),
floating: true,
leading: Icon(Icons.alarm),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, i) {
return Column(
children: <Widget>[
ProductCard(),
Divider(
height: 0,
thickness: 1,
),
],
);
},
childCount: 10,
),
),
],
),
Maybe you can try to use NestedScrollView,like this:
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [SliverAppBar(
leading: Icon(Icons.alarm),
title: Text('Home Scree'),
expandedHeight: kToolbarHeight,
floating: true,
)];
},
body: ListView.builder(
padding: EdgeInsets.zero,
itemCount: 10,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
ProductCard(),
Divider(
height: 0,
thickness: 1,
),
],
);
}),
),
);
}

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),
),
),
],
);
},
),
)

Where to define named parameter 'sliver'

So, I am creating a sliver based AppBar based on this example I found, and am facing the error named parameter 'slivers' isn't defined.
My code somewhat looks like this (I know I am probably putting the sliver in the wrong place, but any help in understanding the issue is appreciated).
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.white,
onPressed: () {},
child: Icon(
CommunityMaterialIcons.plus,
color: Colors.black,
),
),
slivers: <Widget>[ // *problematic sliver here*
SliverAppBar(
pinned: true,
expandedHeight: 256.0,
flexibleSpace: FlexibleSpaceBar(
title: Text('po.'),
),
),
],
body: ListView.builder(
itemCount: tracks.length,
itemBuilder: (BuildContext context, int index) { // the rest of the itembuilder continued here
Indeed slivers field is not defined for Scaffold. Wrap your appbar and listview in NestedScrollView like this:
Widget build(BuildContext context) => Scaffold(
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.white,
onPressed: () {},
child: Icon(
Icons.plus_one,
color: Colors.black,
),
),
body: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
pinned: true,
expandedHeight: 256.0,
flexibleSpace: FlexibleSpaceBar(
title: Text('po.'),
),
),
];
},
body: ListView.builder(
padding: EdgeInsets.all(8.0),
itemExtent: 20.0,
itemBuilder: (BuildContext context, int index) {
return Text('entry $index');
},
)));
Here is fixed gist you provided:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
theme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: Home(),
));
}
class Home extends StatelessWidget {
final tracks = const [
{'title': 'BCS Examination', 'subtitle': 'Something'},
{'title': 'Dhaka University Admission'},
{'title': 'Khulna University Admission'},
{'title': 'Chottogram University Admission'},
{'title': 'Bank Job Exam'},
{'title': 'Bank Job Exam'}
];
#override
Widget build(BuildContext context) => Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.white,
onPressed: () {},
child: Icon(
Icons.info,
color: Colors.black,
),
),
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
pinned: true,
expandedHeight: 256.0,
flexibleSpace: FlexibleSpaceBar(
title: Text('po.'),
),
),
];
},
body: ListView.builder(
itemCount: tracks.length,
itemBuilder: (BuildContext context, int index) {
var trackTitles = tracks[index];
return Text(trackTitles['title']);
}),
));
}
In the body you cold set a SliverList and set the child count as 0.
Something like:
SliverList(
delegate: new SliverChildListDelegate(<Widget>[]),
)
Normally I use it with a CustomScrollView but you could try.