Change all children's font family in Flutter - flutter

Is there a straight forward way to change the font family to a widget and all its children?
my thought was to have an inherited widget and store the font family and call it to get that when creating every text widgets and set its style, but I prefer a simpler way.

You can wrap the widget whose descendants you want to change (e.g. MyWidget()) in a Theme Widget. For example:
Container(
child: Theme(
data: Theme.of(context).copyWith(
textTheme: TextTheme(<your changes here>),
),
child: MyWidget()
)
)

Related

Flutter define icon color by textstyle

I think I've hared that there is a Widget the gets a Textstyle and a list of children. The children can be Text-Widgets or Icon-Widgets and get the defining styles (and with that the color of the Icon) from that parent.
But I can't find that anywhere.
Do I remember that correctly, and if, what Widget was that?
Or am I just wrong about that?
Edit:
I thought it was this, but it don't seam to work the way I thought:
return RichText(
strutStyle: StrutStyle.fromTextStyle(TextStyle(color: Colors.white, fontWeight: FontWeight.w500)),
text: TextSpan(
children: [
TextSpan(text: "Add Object"),
WidgetSpan(child: Icon(Icons.add))
]
),
);
You can make use of the DefaultTextStyle widget which receives a TextStyle entity and will apply it to descendant Text widgets (as long as the descendant Text widgets do not have explicit styles applied: https://api.flutter.dev/flutter/widgets/DefaultTextStyle-class.html
When talking about the icons as well, there is no dedicated widget for that since you would usually define that as part of your overall theme as ThemeData (usually provided in MaterialApp)

Flutter - Paginated Datatable bottom font coloring and layout

I've got here my paginated data table wrapped with a theme widget to add the backgroundcolor:
return Theme(
data: Theme.of(context).copyWith(
cardColor: Color(0xff1D202C),
dividerColor: Color(0xff333333),
),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: PaginatedDataTable(
columns: getColumns(),
source: RecordsSource(),
),
),
);
And I've specified the row color by using color: MaterialStateColor.resolvewith(){} inside my DataRow.byindex method(which is within the DataTableSource, named as RecordsSource above) and it looks like this:
So the problem is - how can I color the font of the pages at the bottom and reduce its height? To be specific, I mean the 1-10 of 11 and < > which is barely visible since the theme of my app is dark bluish.
And another problem is about layout. So the expected amount of rows is 100 and I want it 20 rows per page. However occasionally, there can be - e.g 11 rows only(since the data is from an api), so it will look like this on the second page:
How do I make the table to only show one line on this page?
For detailed code, feel free to visit https://github1s.com/davidp918/KZStats/blob/main/lib/pages/details/map_detail.dart and the paginated datatable code begins at line 233
for changing the color of the bottom counter of pages (1-10 of 20):
wrap the PaginatedDataTable widget with a theme widget, and change the color of "caption" property:
Theme(
data: ThemeData(cardColor: Theme.of(context).cardColor, textTheme: TextTheme(caption: TextStyle(color: Colors.white))),
child:PaginatedDataTable(..

Locally overriding CupertinoTheme with Flutter

I'm working with Cupertino widgets, and need to locally override my global CupertinoTheme, and use CupertinoTheme widget for this purpose. My use case is to force some 'dark' theme when displaying text on top of images, but the issue is general.
In the following sample, I try to change the font size for one text style (from 42px to 21px), but it is not applied: the two texts have the same size (second should be 21px high).
It seems that CupertinoTheme.of(context) does not read the overriden style, contrary to the documentation
Descendant widgets can retrieve the current CupertinoThemeData by calling CupertinoTheme.of
Here is a sample (that can be tested on DartPad):
import 'package:flutter/cupertino.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoApp(
debugShowCheckedModeBanner: true,
theme: CupertinoThemeData(
brightness: Brightness.dark,
textTheme: CupertinoTextThemeData(
navLargeTitleTextStyle: TextStyle(fontSize: 42)
)
),
home: Home()
);
}
}
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Column(
children: [
Text(
'Hello, World #1!',
style: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle
),
CupertinoTheme(
data: CupertinoThemeData(
textTheme: CupertinoTextThemeData(
navLargeTitleTextStyle: TextStyle(fontSize: 21)
)
),
child: Text(
'Hello, World #2!',
style:
CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle
),
),
]
)
);
}
}
You’re getting the theme from the wrong context. The context must be a descendant of the CupertinoTheme widget (or rather the element that will be created from it). Try:
CupertinoTheme(
data: ...,
child: Builder(
builder: (context) => ... CupertinoTheme.of(contex)...
)
)
With the content parameter of the build method you can access anything done by ancestors of the build-method’s widget. Whatever you do in the build method has no effect on it.
Widgets are recipes for creating a tree of Elements. The context parameter that you get in build(er) method is (a reduced interface of) the element created for that widget. The Foo.of(context) methods typically search through the ancestor elements of context to find a Foo. (In some cases there is caching, so it isn’t a slow search.) When you create a tree of widgets in a build method, you’re just creating widgets; the elements will be created after that build method competes. Using a Builder widget, like I did above, delays creation of the widgets in Builder’s builder parameter until after an elements have been created for the Builder (and the widgets above it). So that is a way to get around your problem. Another way would be to create a new StatelessWidget with the widgets that are children of CupertinoTheme in your code, because it will similarly delay the creation of those widgets until after the element for that stateless widget (and its parents) is created.

When user changes the text size in their display settings, my flutter app text size is also changing and it is disturbing nearby widgets

When user changes the text size in their display settings, my flutter app text size is also changing and it is disturbing nearby widgets, there by some part of the UI is becoming unusable. Is there any option to prevent changing of my flutter app text font sizes when system font size changes? If no option is available, how to overcome this problem? Surprisingly there is no much content about this issue on internet. Did anyone face such issues before?No code is req.
You need to set the textScaleFactor of your texts. Like:
Text(
'hello',
textScaleFactor: 1.0,
),
Or you can globally set it to 1.0 by:
MaterialApp(
builder: (BuildContext context, Widget child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: child,
);
},
title: 'Home Page',
);
You can set textScaleFactor: 1 in Text Widget

Flutter - how to get AppBar title foreground color

I have a Flutter app, where on the appBar, I have added a dropdown button. My app supports primary / secondary color changing.
The screenshot below shows an appBar for two different primary colors.
As you can see, the Flutter is able to decide what color to use for app bar text to keep proper readability - white for dark color and black for light color (second app bar).
I would like to set dropdown items' text color identical for the one, used by Flutter app bar text, hence, I would like to retrieve it.
Looking at Theme.of(context) properties, however, didn't give me a clue what color should I use to achieve what I need to.
Below is the code snippet:
final ThemeData _theme = Theme.of(context);
final int index = values.indexWhere((TimeSpan element) => element.value == initialValue.value);
return Theme(
data: _theme.copyWith(
canvasColor: _theme.primaryColor,
brightness: Brightness.dark,
),
child: DropdownButtonHideUnderline(
child: DropdownButton<TimeSpan>(
items: values
.map(
(value) => DropdownMenuItem(
child: Text(
value.toString(),
style: TextStyle(color: _theme.colorScheme.surface),
),
value: value,
),
)
.toList(),
onChanged: callback,
isExpanded: false,
value: values[index],
),
),
);
After a couple of days working with light / dark theme brightness, I figure out, a (possible) solution for the above case.
You can get the desired text color via one of the existing text themes, for instance Theme.of(context).primaryTextTheme.title.color returns color adjusted to current theme brightness.
Flutter renders the widget based on the final theme values it has.
So for example if the child widget has a different theme and the parent widget has a different theme, Flutter's rendering engine will first give preference to the child widget's theme over the parent widget's theme.
So DropdownButton has a theme hardcoded by default which cannot be directly changed as the widget does not accept any parameter to change the theme of the underlying widget(s) and as a result the Theme of the parent widget won't change/alter the theme of DropdownButton. That's the reason why the text Week remains black in both the cases.
If you really want to change the theme you can either alter the source code of DropDownButton or make a custom widget for it. However, simply hardcoding the values for text-color should still do the work.
In order to change the Appbar's text color you will have to manually change the text color as the parent theme suggests that the text color should be white whereas you want it to be black(as per your requirements).
Scaffold(
appBar: AppBar(
title: Text("Weight Overview",color: Colors.black)
)
[...]
)
On OP's request,
You can manually change the Theme of your children at any point of your Widget tree by using the Theme widget and providing it with a theme.
Solution code:
Scaffold(
appBar: AppBar(
title: Theme(
theme: ThemeData(primaryColor: Colors.black),
child: Text("Weight Overview",),
),
),
[...]
)