How to dynamically theme BoxDecoration in Flutter / GetX - flutter

I am using GetX with Flutter and dynamically change Application theme via standard ThemeData. All is working great for properties within ThemeData.
However, I just implemented Drawer widget and wanted to also theme the 'decoration' property within DrawerHeader (of type BoxDecoration). I wanted to theme the color within BoxDecoration depending on selected theme but it only seems to accept constant. I have not find any way to dynamically change it based on the theme.
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const <Widget>[
DrawerHeader(
decoration:
BoxDecoration(color: Get.isDarkMode ? Colors.red : Colors.blue),
I get the following error:
The values in a const list literal must be constants. Try removing the keyword 'const' from the list literal.
It relates to the following part:
color: Get.isDarkMode ? Colors.red : Colors.blue
Any recommendation how to do that?
Thank you.

Felipe - you are right. I spent hours of reading and testing but for some reason I completely missed the obvious thing - was always looking only at Decoration / BoxDecoration itself and not up the tree. Thank you so much for your fast answer. It works now.
Issue was with the following line:
children: const <Widget>[
after removing the const it works - solution:
children: <Widget>[

Render two different drawer headers based on Get.color, instead of rendering one drawer head with variable colors.

Related

Should i use less complex widgets for best flutter performance?

I prefer to use a Column with SizedBox to build space layout ! But my boss keep saying that i should use a Container with padding because container is less complex widget and should perform better. He always says that i should avoid stack widget because is a complex widget. But i think i remember from a flutter video that doesn't matter which widgets you choose, because flutter optimizes it when it builds the three trees ! Is that true ? should i spend time optimizing my widgets with less complex widgets as possible ?
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 24),
Text(
text,
),
],
);
Container(
padding: EdgeInsets.only(top: 24),
child: Text(
text,
),
);
In Flutter padding desing discussion they said that doesn't matter if you use container with padding or specific padding widget. But i'm still in doubt if i should use less complex widget in general.

Why does Flutter need to have a "child: null" line of code when text button is used in a children[] widget?

New to flutter. I'm currently working through a flutter course where I practice adding packages to play sounds by building a xylophone. When adding multiple buttons for each sound file, flutter was telling me "The parameter 'child' is required" and has me insert it at the end of the TextButton with a null property. The code worked fine without it on there but dart analysis kept giving me a warning. Sample code after inserting child listed below.
children: [
TextButton(
onPressed: () {
final player = AudioCache();
player.play('note1.wav');
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.red),
), child: null,
I cannot seem to find why this was warning me but reading the documentation it looks like maybe because it was expecting text for text button? Can anyone explain or point to why it does this?
Thanks in advance.
EDIT
As user #Saddan says, the TextButton class includes box constraints, meaning it will still have a size even without a child.
The real reason why you need a child widget is a bit more boring: There are very few reasons why you would want to have a TextWidget without a child, and even if you did, as I mention later in my answer, a more common approach to this is to use Container, which can be understood as an empty widget, because of this, the child property is considered required on the text widget (with null-safety, you get a compile-time error and without it, you get a lint warning like in the question).
The reason why child: null is added automatically is that flutter doesn't know what you want as your TextButton's child, but I believe you are meant to replace null with whatever else.
ORIGINAL ANSWER
A TextButton should always have a child because if it doesn't it will not display anything, a text button can't size itself so it will always have the same size as its child, you need to put something on the child property or the text button will not know what to look like.
Now, you are passing null as the child, I will have to admit, I didn't think that was possible, I also don't think flutter likes this idea very much (If you activate null-safety, this code will throw a compile-time error). I think you should instead use Container, which is an empty-by-default widget as the child property:
TextButton(
onPressed: () {
final player = AudioCache();
player.play('note1.wav');
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.red),
),
child: Container(),
You can also use the container with some color, some width or some height if you want:
Container(
color: Colors.red,
width: 20,
height: 20,
);
Your assumption is quite right. Its expecting a Widget ,if specific its expecting a TextWidget which consider a label or name of your button. Probably you're using an old version of flutter framework so its accepting null value of child but as I'm using 2.5.3 it's not accepting null value and you must need to provide it.

ButtonStyle padding different from container padding

Why is it that a ButtonStyle's padding property is not equivalent to a Container's padding property in terms of pixels?
I would expect the TextButton and Container text to be aligned when placed together here:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.all(24)),
),
onPressed: () => print('pressed!'),
child: Text('My Button'),
),
Container(
padding: EdgeInsets.all(24),
child: Text('Some other text'),
)
],
);
Both the TextButton and Container theoretically have taken the same padding amount, and yet the texts do not line up. Note the "S" from the Container text does not line up with the "M" from the TextButton, despite them both having the same amount of padding:
Note that the Column's crossAxisAlignment has been set to "start" such that both widgets should align to the left-most side.
Am I missing something about the ButtonStyle's padding property?
Update
I can confirm that iOS and Android does not have the same issue. This issue seems to be isolated to Web and Desktop (macOS/Linux). I have not tested Windows.
So it seems that this is a bug and has been tracked here on GitHub.
As per the comments, a fix was pushed to the master channel of releases in March and I presume will be available in the next 2.3.0 stable release.
For those who want to switch to the latest master to double check that it's working as it should; run:
$ flutter channel master
$ flutter upgrade
You may also need to reinstall any packages before running.

ColoredBox vs Container with color, what's the difference?

Both code does the same job:
ColoredBox(
color: Colors.blue,
child: SizedBox.fromSize(size: Size.fromRadius(100)),
)
And
Container(
color: Colors.blue,
child: SizedBox.fromSize(size: Size.fromRadius(100)),
)
So, what's the benefit of using ColoredBox when it only supports just one property color which is also provided by Container?
Looks like this has now changed according to this post:
https://flutter.dev/docs/release/breaking-changes/container-color
So actually just specifying only the color property in a Container would be optimised under the hood to ColoredBox by default now.
Unless I'm reading it wrong?
Your 2nd code
Container(color: Colors.blue, child: ...)
results in a widget hierarchy that uses a BoxDecoration to paint the background color.
BoxDecoration also covers many cases other than just painting a background color and hence it isn't as efficient as ColoredBox widget, which only paints a background color.
TL;DR:
If your use case is to only provide a background color, go for ColoredBox and not a Container.

Flutter extra / unwanted space above keyboard

I have a weird extra spacing when clicking into a textfield in Flutter, that above the normal iOS keyboard some extra grey box appears. Can anyone help me where this comes from and how to get rid of it? The video shows how it appears.
Thanks!
Found it, thanks for the help!
I have a setup with tabs at the bottom and had in from former tests these 2 properties set to false in the scaffold setup:
child: Scaffold(
// resizeToAvoidBottomPadding: false, <-- caused the extra space
// resizeToAvoidBottomInset: false, <-- caused the extra space
body: buildTabs(context),
This is happens when you have a scaffold that is a child of another scaffold and one of them has backgroundColor: property set to a value. You can set scaffoldBackgroundColor: property in your theme and remove color properties in the scaffold itself and this should fix your issue!
This issue happens when you nest a Scaffold inside another Scaffold.
I added the following property to the outer Scaffold to solve the issue:
Scaffold(
...
resizeToAvoidBottomInset: false,
)
In my case I had this structure which cased the whitespace:
Scaffold(child: PageView(children: [//some containers, Container(child: SingleChildScrollView( child: Column(children: [//some children widgets])))]));
then I moved the SingleChildScrollView from wrapping the column to wrap the first container and that fixed the issue
Scaffold(child: PageView(children: [//some containers, SingleChildScrollView( Container(child: Column(children: [//some children widgets])))]));
This happen because we use white color in scaffold property backgroundColor
which cause an issue.
Remove Color property from Parent Scaffold widget and if you want to use color in parent widget so you can use theme property scaffoldBackgroundColor.