Flutter: FloatingActionButton has no shadows and touch animation - flutter

The default FAB in the demo app has shadows and a ripple effect when touched.
However, when the FAB is moved to another class, it suddenly loses this effect, which makes it look rather plain.
Is it possible to bring the shadows and ripple animations to the plain looking FAB while keeping it in a separate class?
Main.dart
import 'package:test_app/TestItem1.dart';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new TestItem1(),
);
}
}
TestItem1.dart
import 'package:flutter/material.dart';
class TestItem1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'test 1',
),
new Text(
'test1',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
tooltip: 'Increment',
onPressed: null,
child: new Icon(Icons.add),
),
);
}
}

The floating action button is disabled by default if you gave nothing to
onPresss()
if you don't want to give in onPress just pass (){} an anonymous method

Related

Fill Icons with color in Flutter

I'm currently working on a Flutter project. I have been given Icons by the designer.
One of the Icons looks like this
Now I'd like to fill the inside of the Icon with color so that it looks like this
How can I achieve this in flutter? I really tried a lot. Like using ClipRect and other Classes. But none gave the desired results.
Try this one.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
bool _isBluetoothOn = false;
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
IconButton(
onPressed: () async {
print(_isBluetoothOn);
setState(() {
_isBluetoothOn = !_isBluetoothOn;
});
print(_isBluetoothOn);
},
icon: Icon(
_isBluetoothOn ? Icons.favorite : Icons.favorite_border,
color: Colors.greenAccent,
size: 40,
),
),
],
),
),
);
}
}
You can simply ask designer for filled icons too and show them when they are clicked.
So it goes like this:
if button clicked:
show filledIcon
else:
show unfilledIcon
You can code that in Flutter like:
icon:clicked? Icon(filledIcon):Icon(unfilledIcon)
This is the easiest way to do this.

Flutter: How to change the state of a variable in another dart file?

I am currently working on an app; I want to change the value of a String which is declared in another dart file and then pass that changed state to the stateful widget.
I.E;
I create a file called as "Body.dart" file where I have declared a String called as 'scale' who's value initially is "Empty".
Later when a button in another dart file "scale_button" is pressed, I want to assign the string scale = "Hello" in my Body.dart file. So that the stateful widget also displays the same on the screen.
You can use provider(or any other state management) package in that case. In yaml file add, provider: ^4.3.2+4
class HomeApp extends StatefulWidget {
#override
_HomeAppState createState() => _HomeAppState();
}
class _HomeAppState extends State<HomeApp> {
StringProvider _stringProvider;
#override
void initState() {
super.initState();
_stringProvider = Provider.of<StringProvider>(context, listen: false);
}
void updateString() {
_stringProvider.setString('hai');
}
#override
Widget build(BuildContext context) {
StringProvider _stringProvider = Provider.of<StringProvider>(context);
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text(
_stringProvider.str,
style: TextStyle(
fontSize: 22,
),
),
),
RaisedButton(
onPressed: updateString,
child: Text('Click'),
),
],
),
),
);
}
}
// class for storing data(StringProvider.dart)
import 'package:flutter/material.dart';
class StringProvider extends ChangeNotifier { // create a common file for data
String _str = 'hello';
String get str => _str;
void setString(String st) {
_str = st;
notifyListeners();
}
}
When you create a new Flutter project the sample code of the counter shows you how to do this. Check out the comments in the next code:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// here is passing a String to MyHomePage.
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
// And here you can see how to make the widget wait for a variable
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
Full code of Sample Counter App
import 'package:flutter/material.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: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Why is Flutter NotificationListener not catching my notifications?

I am having a problem with the NotificationListener in flutter. I've build a simple testing app because I am struggling with it.
After clicking on the FlatButton the Notification should be dispatched and then caught by the NotificationListener in onNotification.
So the expected console output would be:
"TestNot"
"Bubble"
But all I am getting is "TestNot".
So the notification is not caught by the listener.
Any idea what I could be doing wrong?
Thank you :-)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyNotification extends Notification {
final String title;
const MyNotification({this.title});
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: NotificationListener<MyNotification>(
onNotification: (notification) {
print("Bubble");
return true;
},
child: Center(
child: Column(
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
FlatButton(onPressed: () {print("TestNot"); MyNotification(title: "TestNot").dispatch(context);}, child: Text("TestNot")),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
)),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
When you need a child to notify its parent, you can use NotificationListener.
But, when you need communications to be implemented inversely, in other words, a parent to notify its children, you can use ValueListenableBuilder
A nice doc about it available here:
https://medium.com/flutter-community/flutter-notifications-bubble-up-and-values-go-down-c1a499d22d5f
"Flutter, notifications ‘bubble up’ and values ‘go down’"
You cannot receive the notification at the same level of where it was dispatched. Please refer to docs : https://api.flutter.dev/flutter/widgets/NotificationListener-class.html
NotificationListener class :
A widget that listens for Notifications bubbling up the tree.
I've updated your code to make it work.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyNotification extends Notification {
final String title;
const MyNotification({this.title});
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: NotificationListener<MyNotification>(
onNotification: (MyNotification notification) {
print("Bubble");
return true;
},
child: Center(
child: Column(
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
MyChild(),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
)),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class MyChild extends StatelessWidget {
#override
Widget build(BuildContext context) {
return FlatButton(
onPressed: () {
print("TestNot");
MyNotification(title: "TestNot").dispatch(context);
},
child: Text("TestNot"));
}
}

Can I change the body of a widget using setState?

My application has scaffold.
But I want to change only the body of scaffold.
Normally I use setState() to change the state, but in this case, How can I use setState() or I can do some other way??
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
void onTapped() {
print ("tapped");
// I want to change only body of Scaffold like this
// body: new Text("new body");
};
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:
GestureDetector(
onTap: () => onTapped(),
child:Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
],
),
),
),
);
}
}
If you want to just setState within the body of the scaffold, make the body a stateful widget and call setState within that widget. You can define your own stateless and stateful widgets by extending StatelessWidget or StatefulWidget. It is useful to define a particular thing as its own widget instead of just as a method that returns a widget because of how Flutter compartmentalizes the rebuilding process. If the body of the scaffold is its own widget, only that widget will be rebuilt when you call setState. If you do what the other answer suggests, you will rebuild MyHomePage, which includes the scaffold. On the other hand, if you define a stateful widget with a smaller scope, and then call setState() within that widget, only the widget with the smaller scope will be rebuilt.
For example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
Widget build(BuildContext context) {
print('scaffold rebuilt');
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ScaffoldBody(),
);
}
}
class ScaffoldBody extends StatefulWidget {
#override
_ScaffoldBodyState createState() => _ScaffoldBodyState();
}
class _ScaffoldBodyState extends State<ScaffoldBody> {
int timesTapped = 0;
void onTapped() {
setState(() {
timesTapped++;
});
}
#override
Widget build(BuildContext context) {
print('scaffold body rebuilt');
return GestureDetector(
onTap: onTapped,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times: $timesTapped',
),
],
),
),
);
}
}
You can create a variable Widget _scaffoldBody; to hold the current Scaffold body.
You set an initial value to it, and then call setState when you need to change the body.
Something like this:
class _MyHomePageState extends State<MyHomePage> {
Widget _scaffoldBody;
#override
void initState(){
// Initialize it with the first body you want visible.
_scaffoldBody = GestureDetector(
onTap: () => onTapped(),
child:Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
],
),
),
);
}
// Note: move the onTapped method inside the state so you can call setState;
void onTapped()
// Call setState changing the body
setState((){
_scaffoldBody = Text("new body");
});
};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _scaffoldBody,
);
}
}

Flutter Desktop Application- NoSuchMethodError: Class "Window" has no istance getter 'locales'

I'm pretty new on Flutter and I trying to build a desktop app.
I did all steps of following guide: https://medium.com/flutter-community/flutter-from-mobile-to-desktop-93635e8de64e (Running your own project (compiling the Go desktop project))
Unfornatelly, when I try to run the code I have this error:
NoSuchMethodError: Class "Window" has no instance getter 'locales'
Receiver: Instance of Window
Tried calling: locales
Thank you in advance
The Operating System is Windows 8.1 and following the code. It is the starter one where I just added the debugDefaultTargetPlatformOverride part.
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show
debugDefaultTargetPlatformOverride;
void main(){
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
methods.
);
}
}