How to create a custom AppBar widget? - flutter

I'm new to flutter. I'm trying to create a custom appbar widget and importing the widget in pages.
But I was unable to create the widget.
import 'package:flutter/material.dart';
class AppBar extends StatelessWidget{
#override
Widget build(BuildContext context){
return AppBar(
title: Text('Ordering'),
actions: <Widget>[
IconButton(
onPressed: _incrementCounter,
icon: Icon(Icons.add),
),
BadgeIconButton(
itemCount: _counter,
badgeColor: Color.fromRGBO(37, 134, 16, 1.0),
badgeTextColor: Colors.white,
icon: Icon(Icons.shopping_cart, size: 30.0,),
onPressed: () {}
),
],
);
}
}'

import 'package:flutter/material.dart';
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget {
CustomAppBar({Key key}) : preferredSize = Size.fromHeight(kToolbarHeight), super(key: key);
#override
final Size preferredSize; // default is 56.0
#override
_CustomAppBarState createState() => _CustomAppBarState();
}
class _CustomAppBarState extends State<CustomAppBar>{
#override
Widget build(BuildContext context) {
return AppBar( title: Text("Sample App Bar") );
}
}
Hopefully this helps

class AppBars extends AppBar {
AppBars():super(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
backgroundColor: Colors.white,
title: Text(
"this is app bar",
style: TextStyle(color: Color(Constant.colorBlack)),
),
elevation: 0.0,
automaticallyImplyLeading: false,
actions: <Widget>[
IconButton(
icon: Icon(Icons.notifications),
onPressed: () => null,
),
IconButton(
icon: Icon(Icons.person),
onPressed: () => null,
),
],
);
}

Widget build(BuildContext context) {
return new Scaffold(
appBar: setAppBar(),
body: new Container() // add rest of the UI
);
}
Widget setAppBar() {
return new AppBar(
//backgroundColor: Colors.blue,
//automaticallyImplyLeading: true
elevation: 0.0, // for elevation
titleSpacing: 0.0, // if you want remove title spacing with back button
title: UtilCommonWidget.addTextMedium('About US', Colors.white, 20.0, 1),
actions: <Widget>[
addAppBarActionWidgetProfile(icon, 30.0, 30.0, 15.0) // add your custom action widget
],//Action icon search as search icon, notification icon
leading: new Material( //Custom leading icon, such as back icon or other icon
color: Colors.transparent,
child: new InkWell(
onTap: () {
Navigator.of(context).pop();
},
splashColor: UniQueryColors.colorGradientEnd.withOpacity(.5),
child: new Container(
padding: const EdgeInsets.fromLTRB(12.0, 16.0, 16.0, 16.0),
child: UtilCommonWidget.addImage(Constant.iconBack, 19.0, 10.0))
),
)
);
}

I extended AppBar with my custom widget.
Then passed my parameters to the super class.
class CustomAppBar extends AppBar {
CustomAppBar()
: super(
title: Text('MyApp'),
actions: [
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
);
}

Screenshot (Null Safe):
Full code:
Create this class.
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final Widget child;
final double height;
CustomAppBar({
required this.child,
this.height = kToolbarHeight,
});
#override
Size get preferredSize => Size.fromHeight(height);
#override
Widget build(BuildContext context) {
return Container(
height: preferredSize.height,
color: Colors.red,
child: child,
);
}
}
Usage:
Scaffold(
appBar: CustomAppBar(
height: 100,
child: Column(
children: [
FlutterLogo(size: 56),
SizedBox(height: 8),
Text('Flutter'),
],
),
),
)

Edit to riftninja's answer :
import 'package:flutter/material.dart';
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget {
CustomAppBar({Key key, double height}) : preferredSize =
Size.fromHeight(height), super(key: key);
#override
//final Size preferredSize; // This didnot work for me.
Size get preferredSize => preferredSize; //This should work.
#override
_CustomAppBarState createState() => _CustomAppBarState();
}
class _CustomAppBarState extends State<CustomAppBar>{
#override
Widget build(BuildContext context) {
return AppBar( title: Text("Sample App Bar") );
}
}
This also works for stateless widget.

widget_appbar.dart
class WidgetAppBar extends StatelessWidget implements PreferredSizeWidget {
final Color? backgroundColor;
final Color? textIconColor;
final String? icon;
final String? title;
final double? height;
final List<Widget>? menuItem;
final bool hideBack;
WidgetAppBar({
this.backgroundColor = whiteColor,
this.textIconColor = headingColor,
this.icon,
this.title = '',
this.menuItem,
this.height: kToolbarHeight,
this.hideBack = false,
});
#override
Size get preferredSize => Size.fromHeight(height!);
#override
Widget build(BuildContext context) {
return AppBar(
actions: menuItem,
toolbarHeight: preferredSize.height,
iconTheme: IconThemeData(
color: textIconColor,
),
leading: hideBack
? Container()
: icon == null
? BackButton()
: IconButton(
icon: Image.asset(
icon!,
height: 18,
width: 18,
),
onPressed: () {
Navigator.pop(context, true);
},
),
title: Text(
title!,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: textIconColor,
),
),
backgroundColor: backgroundColor,
centerTitle: true,
);
}
}
How to use?
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: WidgetAppBar(
icon: ic_back_black,
title: 'Toolbar Title',
),
body: SafeArea(
child: Container(),
),
);
}

Related

How can I use a provider in a custom widget to change the variables within a provider?

I tried to create a function to adjust the font size on the setting screen, so I made a provider.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CountPage extends ChangeNotifier{
double _font = 40;
double get font => _font;
change_font_1()
{
_font = 30;
notifyListeners();
}
change_font_2()
{
_font = 35;
notifyListeners();
}
change_font_3()
{
_font = 40;
notifyListeners();
}
And I created an option screen custom widget
Code related to font size:
class Option_page extends StatelessWidget {
late CountPage _countPage;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red[200],
centerTitle: true,
title: Text("설정"),
),
body: Center(
child: Container(
child: Column(children: [
Container(
height: 50,
child: Row(children: [
Container(child: Text('글자크기')),
Container(
width: 300,
color: Colors.cyan,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
onPressed: () {
_countPage.change_font_1();
},
icon: Icon(Icons.looks_one_outlined)),
IconButton(
onPressed: () {
_countPage.change_font_2();
},
icon: Icon(Icons.looks_two_outlined)),
IconButton(
onPressed: () {
_countPage.change_font_3();
},
icon: Icon(Icons.looks_3_outlined)),
],
),
)
]))
]))));
}
}
I connected with the main class:
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home:ChangeNotifierProvider(
create: (BuildContext context) => CountPage()
,child: Quote() ,)
);
}
}
Code related to font size in the main class:
class Quote extends StatelessWidget {
Quote({Key? key}) : super(key: key);
late CountPage _countPage;
#override
Widget build(BuildContext context) {
_countPage = Provider.of<CountPage>(context, listen: true);
return Scaffold(
body: Container(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(
child: IconButton(
onPressed: () {
_countPage.page_down();
},
icon: Icon(Icons.chevron_left))),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Container(
color: Colors.white,
height: 400,
width: 350,
child: Center(
child: Text(
list[_countPage.page]["message"],
style: TextStyle(
fontSize: _countPage.font,
fontFamily: 'snow',
),
textAlign: TextAlign.center,
))),
),
Container(
height: 40,
width: 300,
color: Colors.white,
child: Center(
child: Text(
list[_countPage.page]["author"],
style: TextStyle(fontSize: 20, color: Colors.black),
)))
],
),
],
),
),
);
}
}
The font size does not change even if you run it on Chrome and press the font size change button. I don't know what the problem is.
You can wrap the MaterialApp to access provider on all route
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => CountPage(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
home: Quote(),
),
);
}
}
From current snippet, you didnt assign the CountPage on Option_page.
class Option_page extends StatelessWidget {
Widget build(BuildContext context) {
CountPage _countPage = Provider.of<CountPage>(context, listen: true); //this ibe
return Scaffold(
appBar: AppBar(

ReusableAppbar error, can't be assigned to the parameter type PreferredSizeWidget

I'm trying to create my own reusable appbar for my app but there's some error related with the PreferredSize Widget, I thought by providing some default height will help but it still show the same error how can I fix this ?
I tried applying PreferredSize but it didn't work. Maybe There's something wrong with the way I apply it
Error: The argument type 'ReusableAppbar' can't be assigned to the parameter type 'PreferredSizeWidget?'. (argument_type_not_assignable at [tiket_kerja] lib\screens\settings_pages\user_app_feedback_page.dart:11)
Here's my code:
Reusable appBar code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'button/reusable_back_button.dart';
class ReusableAppbar extends StatelessWidget {
final Function backButtonOnTap;
final String appbarTitleText;
final Color appbarBackgroundColor;
final Widget additionalWidget;
final Widget additionalWidget2;
final double height;
const ReusableAppbar({
required this.backButtonOnTap,
required this.appbarTitleText,
this.appbarBackgroundColor = Colors.white,
this.height = 60,
this.additionalWidget = const SizedBox.shrink(),
this.additionalWidget2 = const SizedBox.shrink(),
Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return AppBar(
iconTheme: IconThemeData(color: appbarBackgroundColor),
automaticallyImplyLeading: false,
centerTitle: false,
backgroundColor: personalBackGround,
toolbarHeight: height,
title: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 13),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: ReusableBackButton(color: primaryColor),
),
Text(
appbarTitleText,
style: primaryColor600Style.copyWith(
fontSize: fontSize16,
),
).tr(),
],
),
),
additionalWidget,
],
),
),
additionalWidget2,
],
),
);
}
}
Here's my code for the usage:
Widget build(BuildContext context) {
return Scaffold(
appBar: ReusableAppbar(
backButtonOnTap: (){
Navigator.pop(context);
},
appbarTitleText: 'Try appbar',
),
);
}
Since appBar parameter of Scaffold Widget accepts PreferredSizeWidget so to create AppBar of your own style you need to implement your ReusableAppbar with PreferredSizeWidget abstract class and also you need to override preferredSize to define size of the appBar this way.
#override
Size get preferredSize => const Size(double.infinity, kToolbarHeight);
Full Code for your ReusableAppbar goes here ;
class ReusableAppbar extends StatelessWidget implements PreferredSizeWidget {
final Function backButtonOnTap;
final String appbarTitleText;
final Color appbarBackgroundColor;
final Widget additionalWidget;
final Widget additionalWidget2;
final double height;
const ReusableAppbar(
{required this.backButtonOnTap,
required this.appbarTitleText,
this.appbarBackgroundColor = Colors.white,
this.height = 60,
this.additionalWidget = const SizedBox.shrink(),
this.additionalWidget2 = const SizedBox.shrink(),
Key? key})
: super(key: key);
/// here kToolbarHeight is the default height provided by flutter
/// you can use your custom height by providing double value.
#override
Size get preferredSize => const Size(double.infinity, kToolbarHeight);
#override
Widget build(BuildContext context) {
return AppBar(
iconTheme: IconThemeData(color: appbarBackgroundColor),
automaticallyImplyLeading: false,
centerTitle: false,
backgroundColor: personalBackGround,
toolbarHeight: height,
title: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 13),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: ReusableBackButton(color: primaryColor),
),
Text(
appbarTitleText,
style: primaryColor600Style.copyWith(
fontSize: fontSize16,
),
).tr(),
],
),
),
additionalWidget,
],
),
),
additionalWidget2,
],
),
);
}
}
You must extends StatelessWidget with PreferredSizeWidget:
class ReusableAppbar extends StatelessWidget with PreferredSizeWidget {
final String text;
ReusableAppbar({Key? key, required this.text})
: preferredSize = Size.fromHeight(50.0),
super(key: key);
#override
Widget build(BuildContext context) {
return AppBar(
title: Text(text),
centerTitle: true,
);
}
#override
final Size preferredSize;
}

Key doesn't work properly when passing it on to child | Flutter

So I have a Scaffold Key in my Scaffold:
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
And in my Scaffold I have a custom Drawer and a custom App Bar:
Scaffold(
key: _scaffoldKey,
backgroundColor: Color(0xFF3FC1C9),
drawer: HomeDrawer(),
body: StartAppBar(_scaffoldKey.currentState?.openDrawer),
),
Im passing the open Drawer function on to the custom AppBar. My custom AppBar accepts the function like this:
class StartAppBar extends StatelessWidget {
void Function()? openDrawer;
StartAppBar(this.openDrawer);
and references it here:
leading: IconButton(
onPressed: () {
openDrawer!();
// _key.currentState!.openEndDrawer();
},
icon: Icon(
Icons.view_headline_rounded,
),
),
The problem is that the drawer doesn't open from the start on. When I switch the bodies of my Screen though through clicking on my bottom bar that I have (code below) the drawer opens. Im guessing that my key has a null value when I load the app for the first time, as a consequence the drawer doesn't open. If that would be the case I would need to set a default value for the key. The whole code is below.
This is the whole code, perhaps it is more relevant then the simplified one:
My class where I create the key looks like this:
class HomeScreen extends StatefulWidget {
final marken;
const HomeScreen({Key? key, this.marken}) : super(key: key);
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
late List<Widget> _widgetOptions;
#override
initState() {
_widgetOptions = <Widget>[
Favorites(),
BodyHomeScreen(
marken: widget.marken,
),
Kontakt(),
];
}
DateTime? lastPressed;
final HideNavbar hiding = HideNavbar();
int _selectedIndex = 1;
void _onItemTap(int index) {
setState(() {
_selectedIndex = index;
});
}
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
key: _scaffoldKey,
backgroundColor: Color(0xFF3FC1C9),
drawer: HomeDrawer(),
body: StartAppBar(_selectedIndex, hiding, lastPressed, _widgetOptions,
_scaffoldKey.currentState?.openDrawer),
bottomNavigationBar: BottomBar(
_onItemTap,
_selectedIndex,
hiding,
),
),
);
}
}
As also seen above im passing the key on to the StartAppBar, that looks like this:
import 'package:flutter/material.dart';
class StartAppBar extends StatelessWidget {
final int selectedIndex;
final hiding;
List<Widget> widgetOptions;
var lastPressed;
void Function()? openDrawer;
StartAppBar(this.selectedIndex, this.hiding, this.lastPressed,
this.widgetOptions, this.openDrawer);
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
final now = DateTime.now();
final maxDuration = Duration(seconds: 2);
final isWarning =
lastPressed == null || now.difference(lastPressed!) > maxDuration;
if (isWarning) {
lastPressed = DateTime.now();
final snackBar = SnackBar(
content: Container(
//color: Colors.white,
decoration: BoxDecoration(
color: Color(0xFF03DAC6),
borderRadius: BorderRadius.circular(20)),
margin: EdgeInsets.fromLTRB(0, 0, 0, 20),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Doppelklick zum verlassen',
textAlign: TextAlign.center,
),
),
),
backgroundColor: Colors.transparent,
elevation: 1000,
behavior: SnackBarBehavior.floating,
duration: maxDuration,
);
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(snackBar);
return false;
} else {
return true;
}
},
child: CustomScrollView(
controller: hiding.controller,
slivers: [
SliverAppBar(
backgroundColor: Color(0xFF3FC1C9),
automaticallyImplyLeading: false,
elevation: 0,
title: Text(
"AutoLab",
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
leading: IconButton(
onPressed: () {
openDrawer?.call();
// _key.currentState!.openEndDrawer();
},
icon: Icon(
Icons.view_headline_rounded,
),
),
centerTitle: true,
expandedHeight: 120,
floating: false,
flexibleSpace: FlexibleSpaceBar(
title: selectedIndex == 1
? Text("Marke auswählen")
: selectedIndex == 2
? Text("Schreibe uns!")
: Text("Deine Modelle"),
centerTitle: true,
),
),
SliverToBoxAdapter(child: widgetOptions.elementAt(selectedIndex)),
],
),
);
}
}
Any ideas how I can fix this behaviour?
It's not necessary that you create a GlobalKey, you only write this :
onPressed: () {
Scaffold.of(context).openDrawer();
},
Because in your widget tree, you already have only one Scaffold, so you don't need to make it unique with a key, so your IconButton knows which Scaffold and Drawer to open.
And now all that remains is to remove the void Function()? openDrawer;

Flutter: How to use animated icon in the AppBar - I want to use this animated icon instead of Animatedless Icon, in the appbar of flutter app

I want to use the animated icon in this AppBar, but can not be done because the animated icon have a stateful widget with "with TickerProviderStateMixin". If I move the whole scaffold to a stateful widget then the "onMenuTap" is not working. The main purpose of the Question is to use the animated icon in the Flutter AppBar.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../FreelanceTheme/AppStyleModeNotifier.dart';
class HomePage extends StatelessWidget with NavigationStates {
final Function onMenuTap;
const HomePage({Key key, this.onMenuTap}) : super(key: key);
#override
Widget build(BuildContext context) {
final appStyleMode = Provider.of<AppStyleModeNotifier>(context);
return MaterialApp(
home: Scaffold(
backgroundColor: Color(0xffE5E5E5),
appBar: AppBar(
elevation: 0,
backgroundColor: appStyleMode.appBarBackgroundColor,
actions: <Widget>[
Switch(
activeColor: Colors.orange,
value: appStyleMode.mode,
onChanged: (value) => appStyleMode.switchMode(),
),
],
leading: IconButton(
tooltip: 'App Settings',
icon: Icon(
FontAwesomeIcons.bars,
color: Colors.white,
),
onPressed: onMenuTap,
),
centerTitle: true,
title: Text(
"Home",
style: TextStyle(
color: Colors.white,
),
),
),
body: FreelancingHomePage(),
),
);
}
}
I want to replace this IconButton with the animated icon in the appbar.
leading: IconButton(
tooltip: 'App Settings',
icon: Icon(
FontAwesomeIcons.bars,
color: Colors.white,
),
onPressed: onMenuTap,
),
Following is the code for the animated icon. I want to use this animated icon in the above appBar.
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController _animationIconController1,
bool isarrowmenu = false;
#override
void initState() {
super.initState();
_animationIconController1 = AnimationController(
vsync: this,
duration: Duration(milliseconds: 750),
reverseDuration: Duration(milliseconds: 750),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
GestureDetector(
onTap: () {
setState(() {
isarrowmenu
? _animationIconController1.reverse()
: _animationIconController1.forward();
isarrowmenu = !isarrowmenu;
});
},
child: ClipOval(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 2.5,
color: Colors.green,
),
borderRadius: BorderRadius.all(
Radius.circular(50.0),
),
),
width: 75,
height: 75,
child: Center(
child: AnimatedIcon(
icon: AnimatedIcons.arrow_menu,
progress: _animationIconController1,
color: Colors.red,
size: 60,
),
),
),
),
),
),
);
}
You can copy paste run full code below
Step 1: You can make this animated icon with StatefulWidget that have VoidCallback onMenuTap
class CustomIcon extends StatefulWidget {
VoidCallback onMenuTap;
CustomIcon({Key key, this.onMenuTap}) : super(key: key);
#override
_CustomIconState createState() => _CustomIconState();
}
class _CustomIconState extends State<CustomIcon> with TickerProviderStateMixin {
AnimationController _animationIconController1;
Step 2: In leading, you can use CustomIcon and pass onMenuTap
home: HomePage(
onMenuTap: () {
print("hi");
},
),
...
leading: CustomIcon(
onMenuTap: () {
onMenuTap();
},
),
working demo
output of working demo
I/flutter (25195): hi
I/flutter (25195): hi
full code
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,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(
onMenuTap: () {
print("hi");
},
),
);
}
}
class HomePage extends StatelessWidget {
final Function onMenuTap;
const HomePage({Key key, this.onMenuTap}) : super(key: key);
#override
Widget build(BuildContext context) {
//final appStyleMode = Provider.of<AppStyleModeNotifier>(context);
return MaterialApp(
home: Scaffold(
backgroundColor: Color(0xffE5E5E5),
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.blue,
actions: <Widget>[
/* Switch(
activeColor: Colors.orange,
value: appStyleMode.mode,
onChanged: (value) => appStyleMode.switchMode(),
),*/
],
leading: CustomIcon(
onMenuTap: () {
onMenuTap();
},
),
centerTitle: true,
title: Text(
"Home",
style: TextStyle(
color: Colors.white,
),
),
),
body: Text("FreelancingHomePage()"),
),
);
}
}
class CustomIcon extends StatefulWidget {
VoidCallback onMenuTap;
CustomIcon({Key key, this.onMenuTap}) : super(key: key);
#override
_CustomIconState createState() => _CustomIconState();
}
class _CustomIconState extends State<CustomIcon> with TickerProviderStateMixin {
AnimationController _animationIconController1;
bool isarrowmenu = false;
#override
void initState() {
super.initState();
_animationIconController1 = AnimationController(
vsync: this,
duration: Duration(milliseconds: 750),
reverseDuration: Duration(milliseconds: 750),
);
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
isarrowmenu
? _animationIconController1.reverse()
: _animationIconController1.forward();
isarrowmenu = !isarrowmenu;
if (widget.onMenuTap != null) {
widget.onMenuTap();
}
});
},
child: ClipOval(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 2.5,
color: Colors.green,
),
borderRadius: BorderRadius.all(
Radius.circular(50.0),
),
),
width: 75,
height: 75,
child: Center(
child: AnimatedIcon(
icon: AnimatedIcons.arrow_menu,
progress: _animationIconController1,
color: Colors.red,
size: 60,
),
),
),
),
);
}
}

In flutter, can you set the appbar backgorund to change base on the value of a dropdown box?

my drop down box cycles through 5 strings
['blue','red','yellow','orange','grey']
I want my appbar title to be that dropdown box and for the value in the dropdown to determine the appbar color
DropDownWidget ddw = DropDownWidget();
var color = {
"blue": Colors.blue,
"red": Colors.red,
"yellow": Colors.yellow,
"orange": Colors.orange,
"grey": Colors.grey,
};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: ddw,
backgroundColor: color[ddw],
),
}
The dropdown (ddw) shows up as the title, no problem.
I made a dictionary with those strings as the keys and the corresponding color as the value, but I am not able to use the string value of the dropdown to change the background.
Any suggestions?
You can copy paste run full code below
You can call setState in onChanged of DropdownButton
code snippet
appBar: AppBar(
backgroundColor: _appbarColor,
...
DropdownButton<Item>(
hint: Text("Select item"),
value: selectedColor,
onChanged: (Item Value) {
setState(() {
selectedColor = Value;
_appbarColor = selectedColor.color;
});
},
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class Item {
const Item(this.name, this.color);
final String name;
final Color color;
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
Color _appbarColor = Colors.blue;
Item selectedColor;
List<Item> colorList = <Item>[
const Item('blue', Colors.blue),
const Item('red', Colors.red),
const Item('yellow', Colors.yellow),
];
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: _appbarColor,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<Item>(
hint: Text("Select item"),
value: selectedColor,
onChanged: (Item Value) {
setState(() {
selectedColor = Value;
_appbarColor = selectedColor.color;
});
},
items: colorList.map((Item item) {
return DropdownMenuItem<Item>(
value: item,
child: Row(
children: <Widget>[
Container(
height: 15,
width: 15,
color: item.color,
),
SizedBox(
width: 10,
),
Text(
item.name,
style: TextStyle(color: Colors.black),
),
],
),
);
}).toList()),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}