how to use the theme of TabBar? - flutter

i created a theme for TabBar, which is:
class AppWidget extends StatelessWidget {
const AppWidget();
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
tabBarTheme: TabBarTheme(
unselectedLabelColor: Colors.black, // and so on
),),
home: const HomePage(),
);},);}
}
when i use TabBar the is no implementation of the theme, which i have been created. How can i use the TabBar theme above inside TabBar implementation?
the code of TabBar is:
class HomeCustomAppBar extends StatelessWidget with PreferredSizeWidget {
#override
Widget build(BuildContext context) {
return Container(
child: AppBar(
// how to get the TabBar Theme here?
bottom:TabBar([]),
),
);
}
#override
Size get preferredSize => Size.fromHeight(140);
}

Ideally you should not need to use directly the TabBarTheme it should be applied automatically to all TabBar's after setting in in the ThemeData. Nevertheless if you still wish to access it you can by just using :
TabBarTheme.of(context)

Related

Keep global ThemeData across screens

Is it possible to set ThemeData globally so you don't have to on the next screens?
Currently after I use the Navigator.pushI have to make sure the new screen Widget have instructions like Theme.of(context).backgroundColor
Is there a way for the app screens/widgets to automatically pick whatever is set in the main.dart theme?
Eg, Here is my main.dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(backgroundColor: Colors.red, primaryColor: Colors.green),
home: LoadingScreen(),
);
}
}
and this is the loadingscreen:
class _LoadingScreenState extends State<LoadingScreen> {
#override
void initState() {
super.initState();
getFiles();
}
void getFiles() async {
await Future.delayed(Duration(seconds: 3));
Navigator.push(context, MaterialPageRoute(builder: (context) {
return StartScreen(file: null);
}));
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Theme.of(context).backgroundColor,
child: Center(
child: Image.asset(
height: 100.0,
)),
),
);
}
}
Without a Theme.of(context).backgroundColor in the Container, the app will load a white page behind the image, instead of red as defined in the ThemeData.
Is that a way to avoid the extensive usage of Theme.of(context).backgroundColor everywhere?
When you set the Scaffolds backgroundcolor in the ThemeData every Scaffold should use that color as a backgroundcolor. On your LoadingScreen the extra Container is unecessery since it would override the Scaffolds backgroundcolor.
Refer to this answer on how to set the backgroundcolor: https://stackoverflow.com/a/55581726/13406356

Text widget font not appearing correctly

I've created a separate page with a StatefulWidget inside my Flutter app, and it has a Text widget inside of it.
However, when testing my app, the text does not render as intended - instead it shows up in a weird font with yellow underlining.
Here's my code:
import 'package:flutter/material.dart';
class ListsPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _ListsPageState();
}
}
class _ListsPageState extends State {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Text('Log in page'),
);
}
}
Results image
Please remove Material Widget just return Text Widget Only, and please try to use the Stateless widget for better performance. Here's the example code
import 'package:flutter/material.dart';
import 'package:show_case/diementions/text_size.dart';
class TextWidget extends StatelessWidget {
const TextWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Text(
'Login Page',
style: kLabelStyle,
);
}
}
This is because of the app styling found in a widget higher in the tree. The text widget searches up the tree for the app default text style or one in another widget. If you wrap the Text widget in a Scaffold, that will include different styling.
See the her comment in the following code for where to try setting the default style:
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 ProviderScope(
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData( //HERE
primarySwatch: Colors.blue,
),
home: const HomeScreen(),
),
);
}
}
Also try wrapping the Text widget like this:
DefaultTextStyle(
style: TextStyle(decoration: TextDecoration.none),
child: Text('Log in page'),
)
Set style in textwidget
Text("", style: TextStyle(decoration: TextDecoration.none),)

Globally remove all drop shadows in Flutter app?

Is there a way to globally remove all drop shadows in Flutter app?
I would like to do that in single place instead of setting elevation: 0 for all MaterialButtons, ElevatedButtons, etc.
I would like set theme, or do it another way, but globally in single palce.
I was looking for attributes in ThemeData, but can't find desired attributes, e.g. for MaterialButtons.
You were on the right track, ThemeData has an attribute for ElevatedButtons, i have made a small example on what you need to remove shadows based on MaterialStateProperty:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
//this is the function that deletes shadows
double getElevation(Set<MaterialState> states) {
return 0;
}
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light().copyWith(
//this is the property that affects elevated buttons
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
elevation: MaterialStateProperty.resolveWith(getElevation)))),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
//this button doesn't have a shadow
return ElevatedButton(
child: const Text("HEY!"),
onPressed: () {},
);
}
}
The solution is pretty straightforward,
ThemeData(
shadowColor: Colors.transparent,
);
gets the job done

How to get the theme that comes with the component in Flutter

How to get the theme that comes with the component in Flutter, such as TextFormField, how do I get the style that comes with his default decoration
I tried the following way, but the obtained theme attributes is null
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
theme: ThemeData(primarySwatch: Colors.blue),
home: TestPage(),
);
}
}
class TestPage extends StatefulWidget {
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
#override
Widget build(BuildContext context) {
var inputTheme = Theme.of(context).inputDecorationTheme;
print(inputTheme.labelStyle); // is null
print(inputTheme.fillColor); // is null
return Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: TextFormField(),
);
}
}
Theme.of(context).inputDecorationTheme
will get you the theme thats used with InputField
Theme.of(context)
will get you everything related to your app theme
try copyWith() and apply() to play around or apply the theme to a component
Theme.of(context).inputDecorationTheme.copyWith();
Some themes depends on the state of the widget itself. That is the case for InputDecoration.
To get the internal theme of a widget what you need is to either get this property if the widget exposes it (which is rare), or intercept it somehow by overriding the class and methods and getting the theme after it is created. That is difficult because usually it runs after the build.
One option is to look at the source code of the widget and copy the code that build the theme into your own code.
For example for InputDecoration.:
TextStyle _getHelperStyle(ThemeData themeData) {
final Color color = decoration!.enabled ? themeData.hintColor : Colors.transparent;
return themeData.textTheme.caption!.copyWith(color: color).merge(decoration!.helperStyle);
}
Another option is to create your own theme, set the properties you need and get them after.
Is the parent of TestPage a MaterialApp widget?
It should look something like this:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'YOUR APP NAME',
theme: ThemeData( //can be omitted if you want the default theme
primarySwatch: Colors.blue,
),
home: TestPage(),
);
}
}
EDIT:
If no InputDecorationTheme is passed to your ThemeData flutter will pass an 'empty' InputDecorationTheme. You can change it for your entire app by creating a ThemeData object and passing it your own InputDecorationTheme.
For example:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'YOUR APP NAME',
theme: ThemeData.light().copyWith(
inputDecorationTheme: InputDecorationTheme(
labelStyle: TextStyle(), //your custom label style
fillColor: Colors.orange //your colour of preference
),
),
home: TestPage(),
);
}
}
Or pass an InputDecoration object to your TextFormField directly
TextFormField(
decoration: InputDecoration(
//change what you want in here
)
)

I don't understand the point of the Theme class in Flutter

So I was working with Flutter and I needed a custom Widget for a ListView where every widget has its own theme based on some data.
The proper way to do it seems to be something like this:
class CustomWidget extends StatefulWidget {
CustomWidget({Key key, this.data}) : super(key: key);
final Color data;
#override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
#override
Widget build(BuildContext context) {
return Theme(
data: ThemeData(primaryColor: widget.data),
child: Builder(builder: (context) {
return Container(
color: Theme.of(context).primaryColor,
);
}),
);
}
}
But if I do it like this, what exactly is the advantage of this?
Specifically applying the color in the container? Why can't I just do color: widget.data?
Wouldn't it make more sense if things like TextTheme automatically applied to every Text() decadence of Theme()?
The ThemeData is used to configure a Theme or MaterialApp widget:
https://api.flutter.dev/flutter/material/ThemeData-class.html
The primaryColor value does not affect the color of the Text widget, from the docs:
The background color for major parts of the app (toolbars, tab bars, etc)
If you want to change the color of the text then you can use the textTheme property:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
accentColor : Colors.black,
textTheme: TextTheme(bodyText2: TextStyle(color: Colors.purple)),
primaryColor : Colors.black
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
primaryColor: is used for the appbar
accentColor: is used to color the foreground
textTheme: will change the color of the text and style it
working example:
https://dartpad.dartlang.org/bba537def9dbfa771400309a4e6415ed