Flutter unable to add title on AppBarTheme - flutter

I was working on a Flutter project and I tried to add the title parameter to AppBarTheme but it gave me an error. This is the code:
#override
Widget build(BuildContext context){
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.green,
accentColor: Colors.pinkAccent,
fontFamily: 'Quicksand',
appBarTheme:
AppBarTheme(textTheme: ThemeData.light().textTheme.copyWith(
title: const TextStyle(
fontFamily: 'Quicksand',
fontSize: 20,
)
)
)
)
);
}
The error was: The named parameter 'title' isn't defined.
How can I solve this?

Here is the way :
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('AppBar titleTextStyle')),
body: Center(child: Text('Hello World')),
);
}
}
void main() {
runApp(
MaterialApp(
theme: ThemeData.light().copyWith(
appBarTheme: AppBarTheme(
backgroundColor: Colors.yellow,
titleTextStyle: TextStyle(color: Colors.black),
backwardsCompatibility: false, // !!!
),
),
home: Home(),
),
);
}

You cannot add title to AppBarTheme, you can only provide the TextStyle for the title in themeData and add the title in AppBar like this:
AppBar(
title: Text(
'your text',
// You need to add this line
style: Theme.of(context).appBarTheme.TextStyle,
),
),

Related

Flutter Theme Dark/Lights Theme toggle doesn't work

there is a dark/light theme toggle function in this snap of code. There is no error when I compile, debuging this code. But It doesn't work.
For example, I never define scaffoldbackgroundColor(0xfffafafa) and What I define color in dark, light theme is Color(0xFFE7626C) and Color(0xFF232B55). But ios simulator only show me backgroundcolor(0xfffafafa).
When I click toggle button, the screen never changes. What's wrong with my code...
import 'package:flutter/material.dart';
import 'package:pomodoro_app/widget/sidebar_widget.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
static final ValueNotifier<ThemeMode> themeNotifier =
ValueNotifier(ThemeMode.dark);
#override
Widget build(BuildContext context) {
return ValueListenableBuilder<ThemeMode>(
valueListenable: themeNotifier,
builder: (_, ThemeMode currentMode, __) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.light,
scaffoldBackgroundColor: const Color(0xFFE7626C),
textTheme: const TextTheme(
displayLarge: TextStyle(
color: Color(0xFF232B55),
),
displaySmall: TextStyle(
color: Color(0xFF232B55),
),
),
cardColor: const Color(0xFFF4EDDB),
),
darkTheme: ThemeData(
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color(
0xFF232B55,
),
cardColor: const Color(0xFFF4EDDB),
textTheme: const TextTheme(
displayLarge: TextStyle(
color: Color(0xFFE7626C),
),
displaySmall: TextStyle(
color: Colors.white,
),
),
),
themeMode: currentMode,
home: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
elevation: 0,
leading: Builder(
builder: (context) => IconButton(
onPressed: () => Scaffold.of(context).openDrawer(),
icon: const Icon(
Icons.menu_rounded,
color: Color(0xFFF4EDDB),
),
),
),
actions: [
IconButton(
icon: Icon(themeNotifier.value == ThemeMode.light
? Icons.dark_mode
: Icons.light_mode),
onPressed: () {
setState(
() {
themeNotifier.value =
themeNotifier.value == ThemeMode.light
? ThemeMode.dark
: ThemeMode.light;
},
);
},
),
],
),
drawer: const SideBar(),
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
"Hello",
)
],
),
),
);
},
);
}
}
That's because the context you are using with
Theme.of(context);
comes from the build method of _HomeScreenState.
So this context is above the MaterialApp which has the Theme.
You have to use a context that is bellow the MaterialApp.
One way to do it is to add a Builder in between your MaterialApp and Scaffold:
return MaterialApp(
title: 'Flutter Demo',
theme: // ...
darkTheme: // ...
themeMode: currentMode,
home: Builder( // <- Insert a builder here.
builder: (context) { // <- Now you'll be using this `context` which is below the `MaterialApp` (and your themes) in the widget tree, so you'll be able to use them.
return Scaffold(
// ...
);
},
);

How to change theme to dark on click on IconButton?

In my application, in the appBar, there is a button that should change the theme to dark. I need to create functionality Provider. How can this be implemented? I just need to change the Scaffold color to black and the text color to white.
My main.dart:
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: const TextTheme(
headline1: TextStyle(fontSize: 50.0, fontWeight: FontWeight.bold),
headline5: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
subtitle2: TextStyle(fontSize: 10.0, color: Colors.black),
bodyText1: TextStyle(fontSize: 14.0, color: Colors.black),
),
),
home: const HomeScreen(),
);
}
My switch button:
appBar: AppBar(
title: const Text('Flutter theme config'),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
},
icon: const Icon(Icons.dark_mode),
)
],
),
Theme provider:
class ThemeProvider extends ChangeNotifier {
}
You can try something like this :
First we provide our Provider globally for the whole application, and then in the attribute theme: we listen for the change.
** main **
void main() async {
runApp(
MultiProvider( // create the provider
providers: [
ChangeNotifierProvider(
create: (_) => ThemeProvider(),
)
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
initialRoute: HomeScreen.routerName,
routes: {
},
theme: Provider.of<ThemeProvider>(context).currentTheme, // listen to the current theme
);
}
}
In the provider we will only have two functions, one to switch to LightMode and the other to DarkMode, then we add it to the currentTheme variable which is the one that listens in the main
** ThemeProvider **
class ThemeProvider extends ChangeNotifier {
ThemeData? currentTheme;
setLightMode() {
currentTheme = ThemeData(
brightness: Brightness.light, // LightMode
scaffoldBackgroundColor: Colors.red,
[...] // more attributes
);
notifyListeners();
}
setDarkmode() {
currentTheme = ThemeData(
brightness: Brightness.dark, // DarkMode
scaffoldBackgroundColor: Colors.green,
[...] // more attributes
);
notifyListeners();
}
}
Finally we create a StatefulWidget to change the isDarkMode variable to call the provider
** Button Home **
class _HomeScreenState extends State<SettingsScreen> {
bool isDarkmode = false; // new variable
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Settings"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
onPressed: () {
final themeProvider =
Provider.of<ThemeProvider>(context, listen: false); // get the provider, listen false is necessary cause is in a function
setState(() {
isDarkmode = !isDarkmode;
}); // change the variable
isDarkmode // call the functions
? themeProvider.setDarkmode()
: themeProvider.setLightMode();
},
icon: const Icon(Icons.dark_mode),
),
),
);
}
}

How to run a method that calls an URL on Flutter right after the app is opened?

Today I have a button that calls the method _launchURL. But I'd like to call this method right after the app opens, without the need to press a button.
import 'package:flutter/material.dart';
import 'package:flutter_custom_tabs/flutter_custom_tabs.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Custom Tabs Example',
theme: ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.light,
),
darkTheme: ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.dark,
),
home: Builder(
builder: (_context) => Scaffold(
appBar: AppBar(
title: const Text('Flutter Custom Tabs Example'),
brightness: Brightness.dark,
),
body: Center(
child: TextButton(
onPressed: () => _launchURL(_context),
child: Text(
'Open Page',
style: TextStyle(fontSize: 17),
),
),
),
),
),
);
}
Future<void> _launchURL(BuildContext context) async {
final theme = Theme.of(context);
try {
await launch(
'https://www.google.com/',
customTabsOption: CustomTabsOption(
toolbarColor: theme.primaryColor,
enableDefaultShare: true,
enableUrlBarHiding: true,
showPageTitle: true,
animation: CustomTabsSystemAnimation.slideIn(),
extraCustomTabs: const <String>[
// ref. https://play.google.com/store/apps/details?id=org.mozilla.firefox
'org.mozilla.firefox',
// ref. https://play.google.com/store/apps/details?id=com.microsoft.emmx
'com.microsoft.emmx',
],
),
safariVCOption: SafariViewControllerOption(
preferredBarTintColor: theme.primaryColor,
preferredControlTintColor: Colors.white,
barCollapsingEnabled: true,
entersReaderIfAvailable: false,
dismissButtonStyle: SafariViewControllerDismissButtonStyle.close,
),
);
} catch (e) {
// An exception is thrown if browser app is not installed on Android device.
debugPrint(e.toString());
}
}
}
Widget build(BuildContext context) {
_launchURL(context); // <= here
return MaterialApp(
title: 'Flutter Custom Tabs Example',
theme: ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.light,
),
.
.
.
.
Or you can add it in initstate, but your method needs a BuildContext to work.

Flutter SearchDelegate: How to change the color of the blue bubbles from text cursor and select?

Flutter SearchDelegate: How to change the color of the blue bubbles in search delegate widget in flutter?
environment:
sdk: ">=2.12.0 <3.0.0"
In my Scaffold-Appbar i have an action with an IconButton and then i call DataSearch. Then i set the ThemeData appBarTheme in the DataSearch. Thats it.
appBar: AppBar(
title: Text(widget.title),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch());
},
),
],
),
class DataSearch extends SearchDelegate<String> {
#override
ThemeData appBarTheme(BuildContext context) {
return ThemeData(
textSelectionTheme: TextSelectionThemeData(
//cursorColor: Colors.red,
selectionHandleColor: Colors.red,
//selectionColor: Colors.white,
), // cursor color
);
}
You can change the color within the textSelectionTheme by setting the selectionHandleColor.
textSelectionTheme: TextSelectionThemeData(
selectionHandleColor: Colors.red, // Change bubble to red
cursorColor: Colors.white,
),
EDIT: Full Example
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
textSelectionTheme: TextSelectionThemeData(
selectionHandleColor: Colors.red,
),
primaryColor: Colors.green,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: TextField(),
),
body: Center(
child: Text('MyApp'),
),
),
);
}
}
Result:

Using AppBarTheme causes default text size?

I'm trying to acheive transparent appbars everywhere in my app using AppBarTheme in my MaterialApp's theme. But it's causing the text size to be the default of 14.0 instead of title size.
I guess it's something to do with TextStyle inheritance, but I don't know much about that.
Example code:
class ExampleScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
ThemeData theme = ThemeData();
return MaterialApp(
theme: theme.copyWith(
appBarTheme: AppBarTheme(
color: Colors.transparent,
brightness: Brightness.light,
elevation: 0,
//I want the defaults, which is why I'm copying an 'empty' ThemeData
//perhaps there's a better way to do this?
textTheme: theme.textTheme,
iconTheme: theme.iconTheme,
),
),
home: Scaffold(
appBar: AppBar(
title: Text('AppBar!'),
),
body: Text('Some text'),
),
);
}
}
This can be achieved by specifying the textTheme inside of the AppBarTheme.
Indeed, the AppBarTheme() has a fully customisable parameter which takes a TextTheme. You almost had it in your question.
Try:
class ExampleScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
ThemeData theme = ThemeData();
return MaterialApp(
theme: theme.copyWith(
appBarTheme: AppBarTheme(
color: Colors.transparent,
brightness: Brightness.light,
elevation: 0,
//I want the defaults, which is why I'm copying an 'empty' ThemeData
//perhaps there's a better way to do this?
textTheme: theme.textTheme.copyWith(
title: theme.textTheme.title.copyWith(fontSize: 20.0),
),
iconTheme: theme.iconTheme,
),
),
home: Scaffold(
appBar: AppBar(
title: Text('AppBar!'),
),
body: Text('Some text'),
),
);
}
}
The textTheme has a title parameter inside of which you can set the fontSize. The default fontSize for titles is 20.0.
Notice the lines:
textTheme: theme.textTheme.copyWith(
title: theme.textTheme.title.copyWith(fontSize: 20.0),
),
You can read more about the TextTheme class here
Each of the parameters is customisable which shows the power of Flutter.
Used the workaround from https://github.com/flutter/flutter/issues/38716
class ExampleScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
ThemeData theme = ThemeData();
var localizedTheme = ThemeData.localize(theme, theme.typography.geometryThemeFor(ScriptCategory.englishLike));
theme = theme.copyWith(
appBarTheme: theme.appBarTheme.copyWith(
color: Colors.transparent,
brightness: Brightness.light,
elevation: 0,
textTheme: localizedTheme.textTheme,
),
);
return MaterialApp(
theme: theme,
home: Scaffold(
appBar: AppBar(
title: Text('AppBar!'),
),
body: Text('Some text'),
),
);
}
}
You could use Theme.of(context) like this:
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: Theme.of(context).copyWith(
appBarTheme: AppBarTheme(
color: Colors.transparent,
brightness: Brightness.light,
elevation: 0,
textTheme: Theme.of(context).textTheme,
iconTheme: Theme.of(context).iconTheme,
),
),
home: Scaffold(
appBar: AppBar(
title: Text('AppBar!'),
),
body: Text('Some text'),
),
);
}
I found a solution. MaterialApp->builder function.
https://api.flutter.dev/flutter/material/MaterialApp/builder.html
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, widget) {
var baseTheme = Theme.of(context);
return Theme(
data: baseTheme.copyWith(
appBarTheme: AppBarTheme(color: Colors.transparent),
),
child: widget);
},
home: HomeView());
}