My goal, if possible, is to add a carousel of buttons and a search bar to a SliverAppBar, that way the search bar is persistent and the carousel just shrinks when scrolling down.
This is the current state without the SliverAppBar:
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:io';
bool get isIOS => !kIsWeb && Platform.isIOS;
class MainStore extends StatefulWidget {
MainStore({Key? key}) : super(key: key);
@override
State<MainStore> createState() => _MainStoreState();
}
class _MainStoreState extends State<MainStore> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: pageBody(context),
);
}
}
Widget pageBody(BuildContext context) {
return Scaffold(
body: ListView(
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 15.0),
scrollDirection: Axis.vertical,
children: <Widget>[
//SEARCH BAR
Container(
width: MediaQuery.of(context).size.width * 15,
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 15.0),
child: Material(
borderRadius: BorderRadius.circular(15.0),
elevation: 5.0,
child: TextField(),
),
),
SizedBox(
height: 15.0,
),
Container(
height: 80.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: new List.generate(10, (int index) {
return new Card(
color: Colors.blue[index * 100],
child: new Container(
width: 100.0,
height: 100.0,
child: new Text("$index"),
),
);
})),
),
SizedBox(
height: 15.0,
),
Column(
children: [
RichText(
textAlign: TextAlign.start,
text: TextSpan(text: 'Premium '),
),
SizedBox(
height: 15.0,
child: Divider(color: Colors.black),
),
GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 4,
physics:
NeverScrollableScrollPhysics(), // to disable GridView's scrolling
shrinkWrap: true,
children: <Widget>[
Container(
padding: const EdgeInsets.all(8),
child: const Text("He'd have you all unravel at the"),
color: Colors.teal[100],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Heed not the rabble'),
color: Colors.teal[200],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Sound of screams but the'),
color: Colors.teal[300],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Who scream'),
color: Colors.teal[400],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution is coming...'),
color: Colors.teal[500],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution, they...'),
color: Colors.teal[600],
),
],
),
],
),
Column(
children: [
RichText(
textAlign: TextAlign.start,
text: TextSpan(text: 'Rones '),
),
SizedBox(
height: 15.0,
child: Divider(color: Colors.black),
),
GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 4,
physics:
NeverScrollableScrollPhysics(), // to disable GridView's scrolling
shrinkWrap: true,
children: <Widget>[
Container(
padding: const EdgeInsets.all(8),
child: const Text("He'd have you all unravel at the"),
color: Colors.teal[100],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Heed not the rabble'),
color: Colors.teal[200],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Sound of screams but the'),
color: Colors.teal[300],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Who scream'),
color: Colors.teal[400],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution is coming...'),
color: Colors.teal[500],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution, they...'),
color: Colors.teal[600],
),
],
),
],
),
Column(
children: [
RichText(
textAlign: TextAlign.left,
text: TextSpan(text: 'Rones '),
),
SizedBox(
height: 15.0,
child: Divider(color: Colors.black),
),
GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 4,
physics:
NeverScrollableScrollPhysics(), // to disable GridView's scrolling
shrinkWrap: true,
children: <Widget>[
Container(
padding: const EdgeInsets.all(8),
child: const Text("He'd have you all unravel at the"),
color: Colors.teal[100],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Heed not the rabble'),
color: Colors.teal[200],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Sound of screams but the'),
color: Colors.teal[300],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Who scream'),
color: Colors.teal[400],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution is coming...'),
color: Colors.teal[500],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution, they...'),
color: Colors.teal[600],
),
],
),
],
)
],
),
resizeToAvoidBottomInset: true,
);
}
This happens when I try to add the carousel to the SliverAppBar, and I can find a way to add the rest of the widgets of the previous image.
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:io';
bool get isIOS => !kIsWeb && Platform.isIOS;
class MainStore extends StatefulWidget {
MainStore({Key? key}) : super(key: key);
@override
State<MainStore> createState() => _MainStoreState();
}
class _MainStoreState extends State<MainStore> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: pageBody(context),
);
}
}
Widget pageBody(BuildContext context) {
bool _pinned = true;
bool _snap = false;
bool _floating = false;
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: _pinned,
snap: _snap,
floating: _floating,
expandedHeight: 200.0,
flexibleSpace: const FlexibleSpaceBar(
// title: Text('SliverAppBar'),
background: FlutterLogo(),
),
actions: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 15.0),
child: Material(
borderRadius: BorderRadius.circular(15.0),
elevation: 5.0,
child: TextField(),
),
),
new Container(
height: 80.0,
child: new ListView(
scrollDirection: Axis.horizontal,
children: new List.generate(10, (int index) {
return new Card(
color: Colors.blue[index * 100],
child: new Container(
width: 50.0,
height: 50.0,
child: new Text("$index"),
));
})))
],
),
SliverToBoxAdapter(
child: Container(
height: 100.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return Container(
width: 100.0,
child: Card(
child: Text('data'),
),
);
},
),
)),
],
),
);
}
You can use FlexibleSpaceBar
's title
to place the horizontal list.
SliverAppBar(
pinned: _pinned,
snap: _snap,
floating: _floating,
expandedHeight: 200.0,
flexibleSpace: FlexibleSpaceBar(
background: FlutterLogo(),
title: Container(
height: 80.0,
alignment: Alignment.bottomCenter,
child: SingleChildScrollView(
primary: false,
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
10,
(int index) {
return Card(
color: Colors.blue[index * 100],
child: Container(
width: 50.0,
height: 50.0,
child: Text("$index"),
));
},
),
),
),
),
),
actions: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 15.0),
child: Material(
borderRadius: BorderRadius.circular(15.0),
elevation: 5.0,
child: TextField(),
),
),
],
)
Also, you can check bottom
on SliverAppBar
.