Dears,
At first am so new to programming and flutter.
I bought an app code and I did the re-skin, but am facing an issue with the splash screen
the code was like this:
import 'package:cirilla/constants/assets.dart';
import 'package:cirilla/constants/constants.dart';
import 'package:flutter/material.dart';
import 'package:ui/painter/zoom_painter.dart';
import 'widgets/zoom_animation.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key, this.color, this.loading}) : super(key: key);
final Color? color;
final bool? loading;
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> with SingleTickerProviderStateMixin {
Size size = Size.zero;
late AnimationController _controller;
late ZoomAnimation _animation;
AnimationStatus _status = AnimationStatus.forward;
#override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 2500),
vsync: this,
)
..addStatusListener((AnimationStatus status) {
setState(() {
_status = status;
});
})
..addListener(() {
setState(() {});
});
_animation = ZoomAnimation(_controller);
}
#override
void didChangeDependencies() {
setState(() {
size = MediaQuery.of(context).size;
});
super.didChangeDependencies();
}
#override
void didUpdateWidget(covariant SplashScreen oldWidget) {
super.didUpdateWidget(oldWidget);
if (!widget.loading! && _controller.status != AnimationStatus.forward) {
_controller.forward();
}
}
#override
Widget build(BuildContext context) {
if (_status == AnimationStatus.completed) return Container();
return Stack(children: [
SizedBox(
width: double.infinity,
height: double.infinity,
child: CustomPaint(
painter: ZoomPainter(color: widget.color!, zoomSize: _animation.zoomSize.value * size.width),
),
),
Padding(
padding: const EdgeInsets.only(bottom: itemPaddingExtraLarge),
child: Align(
alignment: Alignment.center,
child: Opacity(
opacity: _animation.textOpacity.value,
child: Image.asset(Assets.logo, width: 200, height: 200, fit: BoxFit.fitWidth),
),
),
)
]);
}
#override
void dispose() {
super.dispose();
_controller.dispose();
}
}
'''
and was just fine I turned it to this
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
class SimpleAnimation extends StatelessWidget {
const SimpleAnimation({Key? key, this.loading}) : super(key: key);
final bool? loading;
#override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: RiveAnimation.asset('assets/splash/splash.riv',
fit: BoxFit.cover)
),
);
}
}
All I need is just to make it go to the next screen after 5 seconds, I tried many things but nothing sometimes I get a black screen after the splash screen I created with RIVE and most the time it just stuck after playing.
just to note, the following code is in home.dart
return Stack(
children: [
widget.store!.data == null ? const Empty() : buildOnBoarding(context),
SplashScreen(loading: widget.store!.loading, color: Colors.white),
],
);
}
Create method like this.Here future. delayed solve our problem to show animation 5 seconds as splash screen
setdata(BuildContext context) async {
await Future.delayed(const Duration(seconds: 5), () {
SchedulerBinding.instance!.addPostFrameCallback((_) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => WelcomeScreen()),
);
});
});
}
Splash Screen may like this
class SimpleAnimation extends StatelessWidget {
const SimpleAnimation({Key? key, this.loading}) : super(key: key);
final bool? loading;
#override
Widget build(BuildContext context) {
setdata(context);
return Scaffold(
body: Center(
child: Container(
height: 200,
width: 200,
child: RiveAnimation.network(
'https://cdn.rive.app/animations/vehicles.riv',
),
),
),
);
}
}
After splash page
welcome.dart(You must wrap the widget with Scaffold widget.other wise you get black screen
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
child: Text(
"HOME PAGE",
style: TextStyle(fontSize: 50),
),
),
),
);
}
}
SampleCode:
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(home: SimpleAnimation()));
}
setdata(BuildContext context) async {
await Future.delayed(const Duration(seconds: 5), () {
SchedulerBinding.instance!.addPostFrameCallback((_) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => WelcomeScreen()),
);
});
});
}
class SimpleAnimation extends StatelessWidget {
const SimpleAnimation({Key? key, this.loading}) : super(key: key);
final bool? loading;
#override
Widget build(BuildContext context) {
setdata(context);
return Scaffold(
body: Center(
child: Container(
height: 200,
width: 200,
child: RiveAnimation.network(
'https://cdn.rive.app/animations/vehicles.riv',
),
),
),
);
}
}
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
child: Text(
"HOME PAGE",
style: TextStyle(fontSize: 50),
),
),
),
);
}
}
Related
I am making a chat app using flutter. It is loading data from firestore but when I am using annimation in the drawer the chat's aren't loading I don't know the reason if i comment out the animation in the chat screen it works and it works also if comment out if block which contain connection state.waiting without commenting annimation
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:my_flutter_app/chat/messages.dart';
import 'package:my_flutter_app/chat/new_message.dart';
class ChatScreen extends StatefulWidget {
const ChatScreen({Key? key}) : super(key: key);
#override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> with SingleTickerProviderStateMixin{
late AnimationController controller;
late Animation animation;
#override
void initState() {
super.initState();
controller=AnimationController(
duration: Duration(seconds: 2),
vsync: this);
animation=CurvedAnimation(parent: controller, curve: Curves.decelerate);
controller.forward();
animation.addStatusListener((status) {
if(status==AnimationStatus.completed){
controller.reverse(from: 1.0);
}else if(status==AnimationStatus.dismissed){
controller.forward();
}
});
controller.addListener(() {
setState(() {
animation.value;
});
});
}
#override
void dispose() {
super.dispose();
controller.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
margin: EdgeInsets.only(top: 50),
padding: EdgeInsets.all(15),
child: CircleAvatar(backgroundImage: AssetImage('assets/profile.png'),radius: 60),),
Container(
child: Image.asset('assets/welcome.png'),
height: animation.value*100,
),
InkWell(
onTap: (){
showCupertinoDialog(context: context, builder: (context)=>CupertinoAlertDialog(
title: Text('Alert'),
content: Text('Are you sure you want to logout?'),
actions: [
CupertinoDialogAction(child: Text('Yes'),onPressed: (){
FirebaseAuth.instance.signOut();
Navigator.pop(context);
},),
CupertinoDialogAction(child: Text('No'),onPressed: (){
Navigator.pop(context);
},)
],
));
//FirebaseAuth.instance.signOut();
},
child: ListTile(leading: Icon(Icons.logout,color: Colors.white),
title: Text('LOGOUT',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),),
tileColor: Colors.red,),
)
],
),
),
appBar: AppBar(title: Text('Chats'),centerTitle: true,backgroundColor: Colors.green),
body: Container(
child: Column(
children: [
Expanded(child: Messages()),
NewMessage(),
],
),
),
);
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:my_flutter_app/chat/mesui.dart';
class Messages extends StatefulWidget {
const Messages({Key? key}) : super(key: key);
#override
State<Messages> createState() => _MessagesState();
}
class _MessagesState extends State<Messages> {
final auth=FirebaseAuth.instance;
User ?cuser;
#override
void initState() {
// TODO: implement initState
super.initState();
getCurrentUser();
}
void getCurrentUser(){
try {
final user = auth.currentUser;
if (user != null) {
cuser = user;
}
}
catch(e){
print(e);
}
}
#override
Widget build(BuildContext context) {
return StreamBuilder(stream: FirebaseFirestore.instance.collection('chat').orderBy('messaged_on',descending: true).snapshots(),
builder: (context,snaps) {
if(snaps.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
final documents=snaps.data!.docs;
final nowperson=cuser!.email;
return ListView.builder(
reverse: true,
itemBuilder: (ctx,index){
final sender=documents[index]['email'];
bool isMe= sender==nowperson;
return Mesui(documents[index]['text'],isMe);
},
itemCount: documents.length,);
},
);
}
}
i want to use the animated positioned class to change widget position with the launch of the screen without pressing a button!
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
bool selected = false;
#override
Widget build(BuildContext context) {
return SizedBox(
width: 200,
height: 350,
child: Stack(
children: <Widget>[
AnimatedPositioned(
width: selected ? 200.0 : 50.0,
height: selected ? 50.0 : 200.0,
top: selected ? 50.0 : 150.0,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Container(
color: Colors.blue,
child: const Center(child: Text('Tap me')),
),
),
),
],
),
);
}
}
i tried to change it by using a WidgetsBinding like this :
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
selected = true;
});
print(' widget binding : $selected');
});
it works fine but the problem was that it doesnt excuted once, it keeps running and change the value to true! like this :
I copy/past the code you have shared to see what's going on, and it's working just fine for me. I have this code
import 'package:flutter/material.dart';
void main() async {
return runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: MyStatefulWidget(),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
selected = true;
});
print(' widget binding : $selected');
});
}
bool selected = false;
#override
Widget build(BuildContext context) {
return SizedBox(
width: 200,
height: 350,
child: Stack(
children: <Widget>[
AnimatedPositioned(
width: selected ? 200.0 : 50.0,
height: selected ? 50.0 : 200.0,
top: selected ? 50.0 : 150.0,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Container(
color: Colors.blue,
child: const Center(child: Text('Tap me')),
),
),
),
],
),
);
}
}
The animation is run only once, when the postFrameCallback is called. The problem must be elsewhere
I have a MainScreen and SecondScreen. When the drawer item in the MainScreen clicked. It should move to SecondScreen Container widget. But how to do that?
I have set ScrollController for SecondScreen SingleChildScrollView. but how to move to a certain widget?
Create a method in SecondScreen which scroll to the widget?
What if I have 3rd screen which need same functionality.
SecondScreen.dart
import 'package:flutter/material.dart';
ScrollController scrollController = ScrollController();
var containerKey = GlobalKey();
class SecondScreen extends StatefulWidget {
final Key widgetKey;
const SecondScreen({Key key, this.widgetKey}) : super(key: key);
#override
State<SecondScreen> createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
#override
void initState() {
// TODO: implement initState
super.initState();
Scrollable.ensureVisible(
widget.widgetKey,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
controller: scrollController,
child: Column(
children: [
Text('hi'),
Container(
color: Colors.red,
height: 1000,
),
Container(
color: Colors.green,
height: 1000,
),
Container(
key: containerKey,
color: Colors.green,
height: 1000,
),
],
),
),
);
}
}
mainscreen.dart
import 'package:flutter/material.dart';
import 'package:stackoverflow_check/scrollcheck/second_screen.dart';
class MainScreen extends StatelessWidget {
const MainScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: ListView(
children: [
TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SecondScreen(widgetKey: containerKey),
),
);
//scrollController.an
},
child: Text('click'),
)
],
),
),
);
}
}
Main screen
class MainScreen extends StatelessWidget {
const MainScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: ListView(
children: [
TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SecondScreen(widgetNum: 2),
),
);
//scrollController.an
},
child: Text('click'),
)
],
),
),
);
}
}
SecondScreen
class SecondScreen extends StatefulWidget {
final int widgetNum;
const SecondScreen({Key? key, required this.widgetNum}) : super(key: key);
#override
State<SecondScreen> createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
ScrollController scrollController = ScrollController();
var containerKey = GlobalKey();
var container2Key = GlobalKey();
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
Future.delayed(Duration(milliseconds: 100), () {
if (widget.widgetNum == 1) {
Scrollable.ensureVisible(
containerKey.currentContext!,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
} else {
Scrollable.ensureVisible(
container2Key.currentContext!,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
controller: scrollController,
child: Column(
children: [
Text('hi'),
Container(
color: Colors.red,
height: 1000,
),
Container(
color: Colors.green,
height: 1000,
),
Container(
key: containerKey,
color: Colors.green,
height: 1000,
),
Container(
key: container2Key,
color: Colors.blue,
height: 1000,
),
],
),
),
);
}
}
Dark portion is continuously circulating.
Size of dark portion is proportional to amount of data loaded.
Example:- When 40% data loaded then the dark circulating part is 40% of circumference. When 60% data loaded then the dark circulating part is 60% of circumference. So on.
https://youtu.be/a4czRLK6ouE
Here is my attempt to create this animation:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late final AnimationController controller;
double percent = 0.0;
// ** Addition in #mmcdon20 code - Start
changePercent() {
// 20 frame is enough to beat eye, that's why I used
// 50 refresh/second to keep animation smooth
Future.delayed(
const Duration(milliseconds: 20), // Adjust accordingly.
() {
setState(() {
percent += 0.005; // Adjust accordingly.
});
print('........................');
if (percent < 1) {
changePercent();
}
},
);
}
// ** Addition in #mmcdon20 code - End
#override
void initState() {
super.initState();
controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)
..animateTo(1)
..repeat();
// ** Addition in #mmcdon20 code - Start
changePercent();
// ** Addition in #mmcdon20 code - End
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CustomProgressIndicator(
value: percent,
color: Colors.orange,
controller: controller,
width: 200,
height: 200,
strokeWidth: 10,
// curve: Curves.slowMiddle, // ** Eliminationated from #mmcdon20 code
),
// ** Eliminationated from #mmcdon20 code - Start
// Slider(
// value: percent,
// onChanged: (v) {
// setState(() {
// percent = v;
// });
// },
// ),
// ** Eliminationated from #mmcdon20 code - End
],
),
);
}
}
class CustomProgressIndicator extends StatelessWidget {
const CustomProgressIndicator({
Key? key,
required this.color,
required this.value,
required this.controller,
required this.width,
required this.height,
required this.strokeWidth,
this.curve = Curves.linear,
}) : super(key: key);
final Color color;
final double value;
final AnimationController controller;
final double width;
final double height;
final double strokeWidth;
final Curve curve;
#override
Widget build(BuildContext context) {
return RotationTransition(
turns: CurvedAnimation(
parent: controller,
curve: curve,
),
child: SizedBox(
width: width,
height: height,
child: CircularProgressIndicator(
strokeWidth: strokeWidth,
color: color,
backgroundColor: color.withOpacity(.2),
value: value,
),
),
);
}
}
1st Add this:
dependencies:
percent_indicator: ^3.4.0
Then Example:
import 'package:flutter/material.dart';
import 'package:percent_indicator_example/sample_circular_page.dart';
import 'package:percent_indicator_example/sample_linear_page.dart';
void main() {
runApp(MaterialApp(home: Scaffold(body: SamplePage())));
}
class SamplePage extends StatefulWidget {
#override
_SamplePageState createState() => _SamplePageState();
}
class _SamplePageState extends State<SamplePage> {
void _openPage(Widget page) {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => page,
),
);
}
#override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
MaterialButton(
color: Colors.blueAccent,
child: Text("Circular Library"),
onPressed: () => _openPage(SampleCircularPage()),
),
Padding(
padding: EdgeInsets.all(20.0),
),
MaterialButton(
color: Colors.blueAccent,
child: Text("Linear Library"),
onPressed: () => _openPage(SampleLinearPage()),
),
],
),
),
);
}
}
I have a list view and inside the list view, there is a child widget which can grow when user tap on that.
I want to scroll to the bottom of the list when the user taps on the child and it grows.
when I pass callback function from the parent to the child to scroll to the bottom.
and call the function when the user tap on the child.
I get the following error: setState() or markNeedsBuild() called during build.
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
ScrollController _controller = ScrollController();
void scrollToLast() {
print("trying to scroll");
setState(() {
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(microseconds: 300),
curve: Curves.easeInOut,
);
});
}
#override
Widget build(BuildContext context) {
return ListView(
controller: _controller,
children: <Widget>[
MyChildWidget(
scrollToLast: this.scrollToLast,
)
],
);
}
}
class MyChildWidget extends StatefulWidget {
final VoidCallback scrollToLast;
MyChildWidget({
this.scrollToLast,
});
#override
_MyChildWidgetState createState() => _MyChildWidgetState(
scrollToLast: this.scrollToLast,
);
}
class _MyChildWidgetState extends State<MyChildWidget> {
final VoidCallback scrollToLast;
_MyChildWidgetState({
this.scrollToLast,
});
int count = 5;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
setState(() {
this.count += 5;
});
this.scrollToLast();
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: List<Widget>.generate(
this.count,
(int index) => Container(
color: Colors.blue,
height: 30,
margin: EdgeInsets.all(10),
),
),
),
);
}
}
You can copy paste run full code below
You can use WidgetsBinding.instance.addPostFrameCallback
code snippet
void scrollToLast() {
print("trying to scroll");
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(microseconds: 300),
curve: Curves.easeInOut,
);
});
});
}
working demo
full code
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
ScrollController _controller = ScrollController();
void scrollToLast() {
print("trying to scroll");
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(microseconds: 300),
curve: Curves.easeInOut,
);
});
});
}
#override
Widget build(BuildContext context) {
return ListView(
controller: _controller,
children: <Widget>[
MyChildWidget(
scrollToLast: this.scrollToLast,
)
],
);
}
}
class MyChildWidget extends StatefulWidget {
final VoidCallback scrollToLast;
MyChildWidget({
this.scrollToLast,
});
#override
_MyChildWidgetState createState() => _MyChildWidgetState(
/*scrollToLast: this.scrollToLast,*/
);
}
class _MyChildWidgetState extends State<MyChildWidget> {
/* final VoidCallback scrollToLast;
_MyChildWidgetState({
this.scrollToLast,
});*/
int count = 5;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
setState(() {
this.count += 5;
});
widget.scrollToLast();
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: List<Widget>.generate(
this.count,
(int index) => Container(
color: Colors.blue,
height: 30,
margin: EdgeInsets.all(10),
child: Text('$index'),
),
),
),
);
}
}
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: "Demo",
),
);
}
}
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>[
Expanded(child: MyWidget()),
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),
),
);
}
}