Changing the TaskDescription bar color with Flutter - android

Is there a way to change the TaskDescription bar color in a Flutter app?
Here is a link to what I am trying to achieve.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
// Change the status bar color
FlutterStatusbarcolor.setStatusBarColor(Colors.white);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'SMS 2 Server',
color: Colors.white,
theme: ThemeData(
//brightness: Brightness.light,
primarySwatch: primaryWhite,
inputDecorationTheme: InputDecorationTheme(
)
),
home: HomePage(),
);
}
}

you can do like this
Scaffold(
appBar: new AppBar(
backgroundColor: new Color(Color you want),
),
);
or
theme: ThemeData(
primaryColor: YourExpected Color,
)

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
// put the color in here
color: Colors.red,
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Home(),
),
),
);
}
}
Go to the main. dart file and add your color in color attribute under MaterialApp widget

This is not something that Flutter handles. You have to do it from the Android side.
For changing the TaskDescription color of your app, you have to do this in your MainActivity (my example is using Kotlin, but is almost the same with Java).
// Import TaskDescription
import android.app.ActivityManager
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
// Change the color (it's not available on versions before Lollipop)
Timer("ChangingTaskDescriptionColor", false).schedule(1000) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val taskDescription = ActivityManager.TaskDescription(null, null, Color.RED)
setTaskDescription(taskDescription)
}
}
}
Remember to define the color on your colors.xml.
This changes the bar color. You can also set a custom title and icon. But the text color is automatically setted by Android (black or white only).
More information on TaskDescription here
PS: Keep in mind this is something that is not longer available on Android P (don't remember Oreo) as it only shows an Icon. So you should test this on newer versions to be sure it doesn't crash. Maybe check if the API <= than something too.
UPDATE
After trying to make this work on Flutter, I came to the conclusion that the TaskDescription is being override on some point after the first onResume() lifecycle method call. So the only way I could get the result we need, is to use a delay.
Also, it didn't accept the color value from xml, so I've ended using android.graphics.Color.
I've update my code example to show you what I did. And here's the result!

Try use primaryColor attribute of your ThemeData
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'SMS 2 Server',
color: Colors.white,
theme: ThemeData(
//brightness: Brightness.light,
primarySwatch: primaryWhite,
primaryColor: Colors.blue,
inputDecorationTheme: InputDecorationTheme(
)
),
home: HomePage(),
);

If you want to give the title a color of its own, wrap the Text widget with a Container widget and give the Container a color property. eg.
Scaffold(
appBar: AppBar(
title: Container(
color: Colors.red,
child: Text("Your Title")
),
)
)
but I believe the best way has been suggested by #akshay_shahane or #Augusto

The color param in the materialApp Widget should do the work.
In this case the color is green:
MaterialApp(
title: 'Flutter Demo',
color: Colors.green,
theme: ThemeData(
primarySwatch: Colors.orange,
canvasColor: Colors.white,
textTheme: TextTheme()),
home: MyHomePage(title: 'Home'),
);
}

This is absolutely something Flutter handles. You can see it for yourself in the code for the flutter Title widget. The problem is that, as of this writing, there is a bug in the flutter engine that has not allowed the color to be set ever since March of 2019. Soon it will work again, and you will be able to do the following:
Add this to the top of your .dart file:
import 'package:flutter/services.dart';
Add something like this to another part of your app. Do keep in mind that if any of your base widgets like MaterialApp or Scaffold use the Title widget, your setting here may be overwritten if your code is run before the code in those widgets. In that case, you can put the code below into a button or something like that to try it out:
SystemChrome.setApplicationSwitcherDescription(
ApplicationSwitcherDescription(
label: "App Title",
primaryColor: Colors.black.value,
)
);
Again, I will reiterate that this does not work right now because of a bug. If you go to the trouble of compiling the engine yourself with that patch applied (which is not for the faint of heart), you can have it working immediately, but the compilation process for the flutter engine is not very easy to set up.

Related

How to access the app's "in-time" icon in flutter(dart code)?

I want to display the app's icon in my flutter app
I have an app with many icons since I use flutter_launcher_icons
research with google and stackoverflow
I hope you already have set launcher icon if yes then now you can use Use https://pub.dev/packages/application_icon
import 'package:application_icon/application_icon.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
// use AppIcon to show your application icon
child: AppIconImage(),
),
),
);
}
}
Or directly access launcher icon from asset folder

How to access and change a variable from a different file in flutter

I am trying to access and change a variable from a differant file in flutter.
basically, I have created a file called ```colors.dart``` where I'll save the data on the colors that will be used in flutter app.
import 'package:flutter/material.dart';
class colors {
static Color bgColor = Color(0xfff8f8f8);
}
And I wish to change its value when I press on a button
I imported the dart file in my new file and iniside the onpressed function of my button I have:
MaterialApp(
home: Scaffold(
backgroundColor: colors.bgColor,
...
onPressed: () {
setState(() {
colors.bgColor = Color(0xff313131);
});
},
The color inside of bgColor.dart does show up but when I try to change it onPressed (also in an stateful widget) it does not change the scaffold color
If scaffold and button are in the same stateful widget
First of all make sure that backgroundColor: colors.bgColor and setState both are in the same stateful widget, it should work(tested)
If scaffold and button are in different widgets
this way is not dependent on setState so you can use it in both stateless and stateful widgets
Change type of color to ValueNotifier<Color>,
optional: name types using UpperCamelCase
class CustomColors {
static ValueNotifier<Color> bgColor = ValueNotifier(const Color(0xfff8f8f8));
}
wrap scaffold with a ValueListenableBuilder and access color with value property
MaterialApp(
home: ValueListenableBuilder<Color>(
valueListenable: CustomColors.bgColor,
builder: (context, value, child) => Scaffold(
backgroundColor: value,
to change color:
onPressed: () {
CustomColors.bgColor.value = Colors.red;
}
You can use Shared preferences
https://pub.dev/packages/shared_preferences/install
Take a quick look for how to use from anywhere
you can do using the Provider Plugin this.
Color changeColor = colors.bgColor
MaterialApp(
home: Scaffold(
backgroundColor: changeColor,
...
onPressed: () {
setState(() {
changeColor = Color(0xff313131);
});
},

Best Approach To Testing App Appearance In Flutter While App Is In Dark/Light Theme (especially for Dark Theme)

After going through the Flutter docs on testing, I have come to a point in my app where I would like to test both light and dark theme appearance on the app. Integration tests could be an option, however they are "expensive" to run and I would like to leave the consideration of integration tests as a last resort on the matter of testing for dark/light theme app appearance.
This is what I tried with (Widget Tests) testWidgets:
void main() {
testWidgets("Test that the app renders properly in 'Dark Theme'.",
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.dark(),
home: RegistrationHomePage(),
),
);
expect(
SchedulerBinding.instance.window.platformBrightness,
Brightness.dark,
reason: "The test suite should now be testing with app theme set to dark theme.",
);
})
}
However, this test failed. It failed because the Widget Test is still executing this test in light theme instead of dark theme.
What can be done to remedy this situation and how feasible is it to run Widget Tests (focused on app appearance)?
Should the universal default for testing app appearance in flutter be an Integration Test?
Update:
Realistically, I am testing the color that a text widget would be displayed in [both in light theme and dark theme].
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
debugShowCheckedModeBanner: false,
themeMode: ThemeMode.system,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: RegistrationHomePage(),
);
}
}
registration_screen.dart
class RegistrationHomePage extends StatefulWidget {
// Constructor
RegistrationHomePage({Key key}) : super(key: key);
#override
_RegistrationHomePageState createState() => _RegistrationHomePageState();
}
class _RegistrationHomePageState extends State<RegistrationHomePage> {
void setState(fn) {
super.setState(fn);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(
"Welcome to the app",
style: TextStyle(
color: MediaQuery.of(context).platformBrightness == Brightness.dark
? Colors.green.shade900
: Colors.green,
fontWeight: FontWeight.w600,
fontSize: 35.0,
),
textAlign: TextAlign.center,
),
),
);
}
}
test.dart
void main() {
testWidgets("Test that the app renders properly in 'Dark Theme'.",
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.dark(),
home: RegistrationHomePage(),
),
);
final Finder loginTextFinder = find.text("Welcome to the app.");
final Text loginText = tester.firstWidget(loginTextFinder);
expect(
WelcomeText.style.color,
Colors.green.shade900,
reason:
'While the system dark is dark theme, the text color should be dark green',
);
});
}
The test fails. The test fails because the tests have been carried out with the app set to light theme instead of dark theme. There must be something I'm doing wrong here. For now it seems like I cannot set the test app to dark theme which I have tried to do in test.dart with
void main() {
testWidgets("Test that the app renders properly in 'Dark Theme'.",
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.dark(),
home: RegistrationHomePage(),
),
);
});
}
This is the route I would take if I am running a widget test for an app in dark theme:
void main() {
testWidgets("Test that the app renders properly in dark theme",
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(brightness: Brightness.dark),
home: RegistrationHomePage(),
));
// Capture a BuildContext object
final BuildContext context = tester.element(find.byType(MaterialApp));
// Get finders and relevant objects that would be available at first load of MaterialApp()
final Finder welcomeTextFinder = find.text("Welcome to the app");
final Text welcomeText = tester.firstWidget(welcomeTextFinder);
// functions
bool testIsInLightTheme() {
/// return true if the test is in light theme, else false
if (Theme.of(context).brightness == Brightness.light) {
return true;
}
return false;
}
// Here is just a test to confirm that the MaterialApp is now in dark theme
expect(
Theme.of(tester.element(find.byWidget(welcomeText))).brightness,
equals(Brightness.dark),
reason:
"Since MaterialApp() was set to dark theme when it was built at tester.pumpWidget(), the MaterialApp should be in dark theme",
);
// Now let's test the color of the text
expect(
welcomeText.style.color,
testIsInLightTheme() ? Colors.green : Colors.green.shade900,
reason:
"When MaterialApp is in light theme, text is black. When Material App is in dark theme, text is white",
);
});
}
Some notable mentions:
Capturing a BuildContext object in test: https://stackoverflow.com/a/67704136/7181909
Standard instruction (basically some flutter source code that dealt with theme testing) on how theme testing should be approached [By the Flutter team that contributed to theme related testing!]
HEre is my short solution, based on #Alvindera97 answer:
Future<void> testDarkMode(
WidgetTester tester, {
required keyElementToCheckDarkmodeIn,
required keyDarkmodeSwitcher,
}) async {
expect(
Theme.of(tester.element(_finder.key(keyElementToCheckDarkmodeIn))).brightness,
equals(Brightness.light),
);
await tester.tap(_finder.key(keyDarkmodeSwitcher));
await tester.pump();
await tester.pumpAndSettle(_testUtils.delay(DELAY));
expect(
Theme.of(tester.element(_finder.key(keyElementToCheckDarkmodeIn))).brightness,
equals(Brightness.dark),
);
}
Finder key(String keyText) {
return find.byKey(Key(keyText));
}

how to get notified whenever the user changes the os theme in flutter?

I am trying to get notified, whenever the user changes the theme of the operating system. I want to use Provider to accomplish that, however dart Provider needs a Stream that gives a Snapshot, whenerver somthing is changed or getsupdated. So I need to emplement or rather use a Stream, that gives me a snapshot whenever the os theme gets changed.
Here is my code. It is nothing special. But I really want to know how to get this Provider up and running with a Stream
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MaterialApp(initialRoute: '/', routes: {
'/': (context) => MainPage(),
}));
This class is a wrapper for the HomePage. It contains the Provider.
(value: brightnessStream) is a dummy value, and that is what I need to implement.
class MainPage extends StatefulWidget {
#override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
#override
Widget build(BuildContext context) {
return StreamProvider<Brightness>.value(
initialData: Brightness.light,
value: brightnessStream,
child: Home(),
);
}
}
In this class I am listening to the Stream, whenever the brightness changes and displying a text that shows the current theme.
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
final brightness = Provider.of<Brightness>(context);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('App'),
),
body: Center(
child: Text(brightness.toString()),
),
);
}
}
the stream should like somethig like this.
Stream<Brightness> get brightnessStream {
// return stream of os brigtness (os theme)
}
So how is it possible?
Here's how you can set different colors for light and dark mode, the app will automatically switch if the phone is set to dark mode or light mode.
MaterialApp(
theme: ThemeData(
brightness: Brightness.light,
primaryColor: Colors.red,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
// additional settings go here
),
);
You can also get the platform brightness (Brightness.light / Brightness.dark) using
WidgetsBinding.instance.window.platformBrightness
but you will have to use the WidgetsBindingObserver mixin and override the method below
#override
void didChangePlatformBrightness() {
print(WidgetsBinding.instance.window.platformBrightness); // should print Brightness.light / Brightness.dark when you switch
super.didChangePlatformBrightness(); // make sure you call this
}
and then inside the didChangePlatformBrightness you can add to your stream.
This is also duplicate.
click here to view
Thank you for your answers. I solved the Problem like this:
class Theme {
final window = WidgetsBinding.instance.window;
final _controller = StreamController<Brightness>();
Theme() {
window.onPlatformBrightnessChanged = () {
// This callback gets invoked every time brightness changes
final brightness = window.platformBrightness;
_controller.sink.add(brightness);
};
}
Stream<Brightness> get stream => _controller.stream;
}
so I built my own stream

Appbar title under status bar flutter

I am relatively new to flutter so I don't know why my appbar appears like this
Here is the main.dart file
import 'package:testapp/test_page.dart';
import 'package:flutter/material.dart';
void main() {
runApp(Home());
}
class Home extends
StatelessWidget {
#override
Widget build(BuildContext
context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Test App',
theme: ThemeData(primaryColor: Colors.purple),
home: TestPage(),
);
}
}
Here is my testpage.dart
import 'package:flutter/material.dart';
class TestPage extends
StatelessWidget {
#override
Widget build(BuildContext
context) {
return Scaffold(
primary: false,
appBar: AppBar(
title: Text(' Test app'),
),
body: Center(child: Text('Example Test')),
);
}
}
I tried using SafeArea it didn't work. Thank you
here is what i solved similar issue.
Simply wrap your Scaffold widget with SafeArea Widget
SafeArea(
child: Scaffold()
)
You can find more detail about SafeArea Widget in this link
Flutter SafeArea Widget
Hope it will help
Happy coding
You have primary property set to false.
Whether this scaffold is being displayed at the top of the screen.
If true then the height of the appBar will be extended by the height
of the screen's status bar, i.e. the top padding for MediaQuery.
https://api.flutter.dev/flutter/material/Scaffold/primary.html
change the primary value to true and tell me result:
Scaffold(
primary: true, // this line
appBar: AppBar(......
Edit:
MaterialApp cant be a child of statelessWidget. use it as the main Widget
runApp(MaterialApp(
......
))
Thank you much guys, I created a new project then I realised it was caused by a bug from one of the libraries I installed. It's totally fixed now ♥️

Categories

Resources