i want to create an appbar that look like this. i've been trying to use sliverappbar and i can't change the color when the background change the opacity. i want to create an app bar look like this when i scroll down
been trying to search for more relate sliverappbar, or related still didnt find how to create it
and this what i've been trying to do already
CustomScrollView(
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
slivers: <Widget>[
SliverAppBar(
title: Container(
child: Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(5)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Icon(
Icons.search,
size: 15,
color: Colors.grey,
),
Text(
'Cari di Toki',
style: TextStyle(
color: Colors.grey,
fontSize: 15,
),
)
],
),
),
),
)
],
),
),
leading: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.3),
borderRadius: BorderRadius.circular(50)),
child: Icon(Icons.arrow_back, color: Colors.white),
),
pinned: _pinned,
snap: _snap,
floating: _floating,
stretch: true,
expandedHeight: 350,
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.black),
flexibleSpace: FlexibleSpaceBar(
stretchModes: [StretchMode.zoomBackground],
centerTitle: true,
background: Image.network(
widget.product.imageUrl,
fit: BoxFit.cover,
),
),
actions: [
Consumer<WishlistProvider>(builder: (context, wp, _) {
return Badge(
toAnimate: true,
animationType: BadgeAnimationType.slide,
position: BadgePosition.topEnd(top: 5, end: 7),
badgeContent: Text(wp.wishListList.length.toString()),
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.3),
borderRadius: BorderRadius.circular(50)),
child: IconButton(
onPressed: () {
Navigator.of(context)
.pushNamed(WishListScreen.routeName);
},
icon: const Icon(Icons.favorite, color: Colors.white),
),
),
);
}),
SizedBox(width: 3),
Consumer<CartProvider>(builder: (context, cp, _) {
return Badge(
toAnimate: true,
animationType: BadgeAnimationType.slide,
position: BadgePosition.topEnd(top: 5, end: 7),
badgeContent: Text(cp.cartlist.length.toString()),
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.3),
borderRadius: BorderRadius.circular(50)),
child: IconButton(
onPressed: () {
Navigator.of(context).pushNamed(CartScreen.routeName);
},
icon:
const Icon(Icons.shopping_cart, color: Colors.white),
),
),
);
}),
],
),
SliverToBoxAdapter(
child: SizedBox(
height: 20,
child: Text(
widget.product.title,
style: TextStyle(color: Colors.black),
),
),
),
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: 20,
),
),
],
),
CodePudding user response:
you can listen offset from ScrollController
and update your appbar color base on it.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const App(),
);
}
}
const startColor = Colors.transparent;
const targetColor = Colors.red;
const startIconColor = Colors.red;
const targetIconColor = Colors.white;
class App extends StatefulWidget {
const App({Key? key}) : super(key: key);
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
final scrollController = ScrollController();
final appBarColorTween = ColorTween(begin: startColor, end: targetColor);
final iconColorTween = ColorTween(begin: startIconColor, end: targetIconColor);
double lerp = 0.0;
Color get appBarColor => appBarColorTween.transform(lerp) ?? startColor;
Color get iconColor => iconColorTween.transform(lerp) ?? startIconColor;
@override
void initState() {
scrollController.addListener(listener);
super.initState();
}
@override
void dispose() {
scrollController.removeListener(listener);
super.initState();
}
void listener() {
var offset = scrollController.offset;
setState(() => lerp = offset < 300 ? offset / 300 : 1);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: appBarColor,
leading: Icon(Icons.backspace, color: iconColor),
),
extendBodyBehindAppBar: true,
body: ListView.builder(
controller: scrollController,
itemCount: 100,
itemBuilder: (context, index) {
return Card(
margin: const EdgeInsets.all(5),
child: Container(
color: Colors.blue[100 * (index % 9 1)],
height: 80,
alignment: Alignment.center,
child: Text(
"Item $index",
style: const TextStyle(fontSize: 30),
),
),
);
},
),
);
}
}