How to set a text background with Flutter? - flutter

I'm very new to flutter but I'm interested in learning it pretty much from the beginning.
Right now I'm trying such a basic thing as changing the background color of some text, but I'm stuck.
import 'package:flutter/material.dart';
void main() {
final barColor = const Color(0xFFD63031);
var app = MaterialApp(
home: Scaffold(
backgroundColor: barColor,
),
);
Center(
child: Text('My Text',
textDirection: TextDirection.ltr,
),
);
runApp(app);
}
I do understand why the text doesn't show but I've been working on this for days now and I have tried a lot of different things without succeeding, so any help would be very appreciated.
Thank You

TL;DR - (Updated 07-08-2019)
Using style property (backgroundColor)
Text(
'Some text...',
style: TextStyle(backgroundColor: Colors.blue),
)
Using style property (background)
Text(
'Some text...',
style: TextStyle(background: Paint()..color = Colors.blue),
)
Using a DecoratedBox
const DecoratedBox(
decoration: const BoxDecoration(color: Colors.blue),
child: const Text('Some text...'),
);
Long answer
First of all, welcome to Flutter and StackOverflow :)
That happens because are misunderstand the way you should develop with Flutter.
As opposed to what happens with other architectures where you start in the main() function, instantiate your vars/objects and develop your flow from there, with Flutter you start your widget tree from your main() function as well, usually with a MaterialApp or CupertinoApp and fit in all its children to create your app.
So, as an example to get what you want, you must add your Center widget as the body of your Scaffold and then give a TextStyle to your Text widget, providing the property color. I gave it blue, but you can give it anything else you want. Thereby, this is your refactored code:
void main() => runApp(
MaterialApp(
home: Scaffold(
backgroundColor: const Color(0xFFD63031),
body: Center(
child: Text(
'MyText',
textDirection: TextDirection.ltr,
style: TextStyle(
background: Paint()..color = Colors.blue,
),
),
),
),
),
);
that will provide the following result
I suggest you take a look at the Awesome Flutter repo where you have a lot of good Flutter content to start with that can really help you out.

Simple you can set it in style property..
Text(
'My Text...',
style: TextStyle(backgroundColor: Colors.grey),
)
You can set this many properties to text in style: TextStyle()
{ bool inherit = true,
Color color,
Color backgroundColor,
double fontSize,
FontWeight fontWeight,
FontStyle fontStyle,
double letterSpacing,
double wordSpacing,
TextBaseline textBaseline,
double height,
Locale locale,
Paint foreground,
Paint background,
List<Shadow> shadows,
List<FontFeature> fontFeatures,
TextDecoration decoration,
Color decorationColor,
TextDecorationStyle decorationStyle,
double decorationThickness,
String debugLabel,
String fontFamily,
List<String> fontFamilyFallback,
String package
}

Related

Create custom TextStyle class on Flutter

How can I create a custom TextStyle class in flutter? For example I have several buttons and want the text inside to all be the same fontSize and color but I don't want to repeat the TextStyle inside of each Text widget, but instead create something such as CustomTextStyle that I could use in the place of the TextStyle itself.
Is there a way to do this?
Create a separate class names CustomTextStyle and add the styles inside them like:
class CustomTextStyle {
static const TextStyle nameOfTextStyle = TextStyle(
fontSize: 24,
color: Colors.green,
fontWeight: FontWeight.bold,
);
}
Now you can use it in Text widget like:
Text('Lorem Ipsum',
style: CustomTextStyle.nameOfTextStyle,
)
To define your button or text style globally, you need to use theme.
For example, you can define a custom theme for TextButton :
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
textStyle: MaterialStateProperty.all(
const TextStyle(fontSize: 20),
),
),
),
[...]
There are three ways to do this:
Using Theme:
You can declare multiple TextStyles separately in Theme based on widgets, for e.g. AppBar's TitleTextTheme, AppBar's ToolbarTextTheme, Button's TextTheme, General TextTheme for the whole app, or based on ThemeMode, for e.g. Dark Mode or Light mode, you can combine these two Widgets based and ThemeModes based as well.
To do this, Create a class called ThemeModel for example, Create the ThemeData Variables in it in which you'll declare these TextThemes and use it in your MaterialApp in main.dart as
MaterialApp(
...,
theme: ThemeModel().lightMode,
darkTheme: ThemeModel().darkMode,
)
Using a Custom Text Widget.
const CustomText extends StatelessWidget {
final String text;
const CustomText(this.text, {Key? key}): super(key:key);
#override
Widget build(BuildContext context) {
return Text(
text,
style: TextStyle(
color: YourColor,
fontSize: YourSize,
fontWeight: YourFontWeight
),
);
and use it as,
ElevatedButton(
onPressed: (){},
child: CustomText('Click Me'),
)
This way the TextStyle will remain same wherever you'll use this widget.
Using Custom TextStyle:
class CustomTextStyle {
static const TextStyle textStyle = TextStyle(
color: YourColor,
fontSize: YourSize,
fontWeight: YourFontWeight
);
}
and, use it as:
ElevatedButton(
onPressed: (){},
child: Text('Click Me',
style: CustomTextStyle.textStyle,
),
)
Hope, you understand that every one of these methods have their own utility and can be customized way further to make your app development easy.

How to edit the flappy_search_bar flutter package?

I want to edit some features of the flappy_search_bar
As you see see the loading spinner is blue and I can't seem to edit this to any alternate color. I also am unable to edit the cursor color which is also blue.
Here is a copy of my current code block:
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SearchBar<Post>(
searchBarPadding: EdgeInsets.symmetric(horizontal: 20),
headerPadding: EdgeInsets.symmetric(horizontal: 10),
listPadding: EdgeInsets.symmetric(horizontal: 10),
onSearch: _getALlPosts,
hintStyle: TextStyle(color: Colors.black87),
hintText: 'Search',
iconActiveColor: Colors.deepPurpleAccent,
// cursorColor: Colors.deepPurpleAccent,
// loader: Colors.deepPurpleAccent,
textStyle: TextStyle(
fontFamily: 'OpenSans',
fontSize: 18.0,
),`
So far, I have tried editing directly within the search bar as seen above, adding extension code as follows:
class Styling extends SearchBar {
Styling(this.cursorColor);
final Color cursorColor;
static const accentColor = Colors.deepPurpleAccent;
#override
Widget build(BuildContext context) {
return Theme(
// data: Theme.of(context).copyWith(
// cursorColor: Theme.of(context).accentColor,
// ),
);
}
}
I have also tried editing the package files directly but this hasn't been a success either.
Has anyone suggest how to edit the cursor color and loading spinner color of the flappy_search_bar package?
I've been trying to do this too and managed to get it done.
To edit your cursor, apply the following to your top level MaterialApp under ThemeData :
cursorColor: Colors.red,
cupertinoOverrideTheme: CupertinoThemeData(
primaryColor: Colors.red,
),
This sets the color of the Cursor in ALL TextFields , I don't know how to edit it just for the TextField in the flappy_search_bar widget
For the loading indication, add this under the SearchBar you're using:
SearchBar<SomeClass>(
....
loader: const Center(child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Colors.red))),
....
);
This is what the widget does internally if you look at the source.
Change Colors.red to whatever color you need.
Hope that helps.

How to set color of all text in a specific container in flutter?

I don't want to change the text color of the whole app. Just all the text inside a container. Can I wrap it with some other widget or something for this ?
To apply certain TextStyle properties only to a subtree of your app. You can use DefaultTextStyle
DefaultTextStyle(
child: Container(child: /* your subtree */),
style: TextStyle(color: Colors.red),
),
as a comment pointed out, this replaces all defaults, not just the color. This can be mitigated by using the merge constructor:
DefaultTextStyle.merge(
child: Container(child: /* your subtree */),
style: TextStyle(color: Colors.red),
),
flutter's answer is good in my opinion. But the power of ThemeData is more than you think. Here is the official documentation about Themes for part of an application.
You could provide a Theme to wrap your container to provide a new theme. Here is two way to slove it:
1. Creating unique ThemeData
/*Not recommended, this could make a totally different If you just want a little part changed.*/
Theme(
// Create a unique theme with "ThemeData"
data: ThemeData(
textTheme: /* Your Text Theme*/,
),
child: Container(
onPressed: () {},
child: Text("Your Text Here"),
),
);
2. Extending the parent theme
Theme(
// Find and extend the parent theme using "copyWith". See the next
// section for more info on `Theme.of`.
data: Theme.of(context).copyWith(textTheme: /* Provide your theme here! */),
child: Container(
child: Text("your text here"),
),
);
You could also use existed theme with a little changed:
Theme.of(context).textTheme.copyWith(
body1: Theme.of(context).textTheme.body1.copyWith(color: Colors.red),
)
Use DefaultTextStyle.merge to keep your theme and just change the color.
DefaultTextStyle.merge(
style: TextStyle(color: Colors.grey[400]),
child: Column(...),
)
If you are using the MaterialApp widget you could use the theme property of it and set different Text themes and call them anywhere in your app. For example the following code defines 3 different text themes:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Time Tracker",
theme: ThemeData(
textTheme: TextTheme(
headline: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold,color: Colors.blue),
title: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic,color: Colors.red),
body1: TextStyle(fontSize: 14.0, fontFamily: 'Hind',color: Colors.yellow),
),
),
home: LandingPage(),
);
}
}
You can then call a particular theme(headline) anywhere in your app like this:
Text('Home Page',style: Theme.of(context).textTheme.headline,)
Which gives you the headline TextTheme
I have functions for all my styles
TextStyle largeTextStyle() => TextStyle(fontSize: 150);
then I just do
Text("blah", style:largeTextStyle())

Flutter - How to change IconButtons size with Theme

I have a Row with multiple IconButtons and I need to change their color and size.
I managed to change the color, but I'm not able to change the icons size.
IconTheme(
data: IconThemeData(size: 48.0, color: Colors.yellow),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.delete),
onPressed: () => null,
),
IconButton(
icon: Icon(Icons.file_upload),
onPressed: () => _addPhoto(false),
),
IconButton(
icon: Icon(Icons.camera_alt),
onPressed: () => _addPhoto(true),
),
],
),
),
If I set the size within the IconButtons with iconSize it works, but with IconTheme it doesn't.
How can I fix it?
As defined in the official docs, link here:
This property must not be null. It defaults to 24.0. The size given here is passed down to the widget in the icon property via an IconTheme. Setting the size here instead of in, for example, the Icon.size property allows the IconButton to size the splash area to fit the Icon. If you were to set the size of the Icon using Icon.size instead, then the IconButton would default to 24.0 and then the Icon itself would likely get clipped.
Therefore, IconButton needs to be given the iconSize property as this overrides the IconTheme size property. If you want your button to have size derived from IconTheme then you should make your custom IconButton which sets the iconSize for you. For example:
class CustomIconButton extends StatelessWidget {
CustomIconButton({Key key, this.onPressed, this.icon});
final Function onPressed;
final Icon icon;
#override
Widget build(BuildContext context) {
IconThemeData iconThemeData = IconTheme.of(context);
return IconButton(
onPressed: onPressed, iconSize: iconThemeData.size, icon: icon);
}
}
Use iconTheme of ThemeData like so and all your icons will be size 35 with the below code:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
iconTheme: IconThemeData(
size: 35.0,
),
),
home: HomePage(),
);
}
}
First, check if you are in a layout area that uses the primary or default theme. Whats that? Places on a layout that uses the primary color.
ThemeData(
primaryColorLight: Colors.blueAccent[100],
primaryColor: Colors.blueAccent[200],
primaryColorDark: Colors.blueAccent[700],
accentColor: Colors.yellow[700],
iconTheme: IconThemeData(
color: Colors.yellow[700],
size: 28
),
accentIconTheme: IconThemeData(
color: Colors.yellow[700],
size: 32
),
primaryIconTheme: IconThemeData(
color: Colors.yellow[700],
size: 24
),
);
If you are on a primary area (places on a layout that uses the primary color) the accentIconTheme will be used
Otherwise the primaryIconTheme
The IconTheme I do not know for now, so anyone feels free to edit or put on a comment
The icon button was not picking the Icon Size defined in the Theme. Instead, I have to wrap the icon inside of the icon button in iconThemeData.
icon: IconTheme(
data: Theme.of(context).copyWith().iconTheme,
child: Icon(
Icons.search,
),
),
onPressed: () {},
),
This fixed the problem but it's not a good practice to wrap the Icon every time for the theme. There must be a proper solution for that.
make your raw a row of Icons (not IconButton).
then wrap your Icon with a widget that can be taped Like (InkWell or GestureDetector) to take advantage of the (onTap function) .
it’s not a good way actually but it will probably solve your problem .

Custom style or theme for Expansion Tile Header, Flutter

Is there any way to apply custom theme for ExpansionTile. In my case, I want to have the different background colour for Header and children of the expansion tile but When ever the ExpansionTile is expanded, Headers background color changes to that of children?
To apply a custom Theme to any widget, just wrap it with the Theme() widget.
and then specify your custom theme in the data field of the widget.
Theme(
data: ThemeData(/*specify your custom theme here*/),
child: ExpansionTile() /*or any other widget you want to apply the theme to.*/
)
In your case, to customise the header in ExpansionTile,
when ExpansionTile is closed
the style of header text i.e. title depends on
ThemeData.textTheme.subhead (in flutter 2 it's ThemeData.textTheme.subtitle1)
whereas, the style of the arrow icon depends
on ThemeData.unselectedWidget (in flutter 2 it's ThemeData.unselectedWidgetColor)
when ExpansionTile is open
the color of both the widgets depends on ThemeData.accentColor
In a similar fashion you can customise almost any part of the expansion tile by tweaking the theme. For more details check out this link.
Since flutter is built with flexibility in mind. You can do almost anything you want. Create almost any UI you want.
Following the idea of #user3315892, you can implement your own stateful widget for the ExpansionTile, so that you can control what colours you want the header and children to be when the header is expanded or collapsed.
The following example only changes the text foreground and background colours of the header when the expansion tile is expanded or collapsed, but you can do the same for the children widgets.
class CustomExpansionTile extends StatefulWidget {
#override
State createState() => CustomExpansionTileState();
}
class CustomExpansionTileState extends State<CustomExpansionTile> {
bool isExpanded = false;
#override
Widget build(BuildContext context) {
return ExpansionTile(
title: Container(
child: Text(
"HEADER HERE",
style: TextStyle(
color: isExpanded ? Colors.pink : Colors.teal,
),
),
// Change header (which is a Container widget in this case) background colour here.
color: isExpanded ? Colors.orange : Colors.green,
),
leading: Icon(
Icons.face,
size: 36.0,
),
children: <Widget>[
Text("Child Widget One"),
Text("Child Widget Two"),
],
onExpansionChanged: (bool expanding) => setState(() => this.isExpanded = expanding),
);
}
}
I found another way to do it. I don't know if this is the best way but it's simpler for me.
To change the ExpansionTile color, you can wrap it with a Container and give it a color. This will change the entire color of the ExpansionTile, both collapsed and expanded.
But if you want a different color for the children, you can also wrap them with a Container and set another color there. However, keep in mind that you have to "expand" that Container to occupy all the available space (you can do it by setting width and height parameters properly).
Btw, that doesn't change the arrow color.
Widget expansionTileTest(context) {
return Container(
color: Colors.grey,
child: ExpansionTile(
title: Text(
"Title",
style: TextStyle(color: Colors.black),
),
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.1,
width: MediaQuery.of(context).size.width,
color: Colors.yellow,
child: Center(child: Text("Hi")),
),
],
),
);
}
Collapsed
Expanded
You can set color of header and then body/children wrap in Container and set color to that container.
I used this code to make the trailing ion color Black.
Theme(
data: Theme.of(context).copyWith(accentColor: Colors.black),
child: ExpansionTile(
backgroundColor: Colors.white,
title: Text(
'Title Exmample',
style: TextStyle(color: Colors.black),
),
leading: CircleAvatar(
backgroundColor: Colors.black.withOpacity(.07),
child: Icon(
Icons.apps_outlined,
color: Theme.of(context).primaryColor,
)),
children: _buildTiles(Theme.of(context).primaryColor, Colors.black.withOpacity(.07), context),
),
);
If you want the ExpansionTile title to remain the same color whether closed or expanded, you can set it's style:
ExpansionTile(
title: Text('HEADER HERE', style: TextStyle(color: Colors.red)),
...
),
Additional styling for ExpansionTile is an open feature request:
Feature request: More styling of ExpansionTile #15427