I have this code that makes the icon rotate clockwise. I want to make it rotate anticlockwise. how can I do that?
animationController =
AnimationController(vsync: this, duration: Duration(seconds: 3))
..repeat(reverse: true);
RotationTransition(
turns: animationController,
child: Icon(Icons.settings_sharp),
alignment: Alignment.center,
)
Concerning RotationTransition widget rotation direction is manipulated by turns property.
When widget rotates clockwise controllers value goes from 0.0 to 1.0.
To rotate in opposite direction you need value to go from 1.0. to 0.0.
To achieve that, you can set up Tween:
final Tween<double> turnsTween = Tween<double>(
begin: 1,
end: 0,
);
And animate this tween in turns property with any AnimationController you need:
child: RotationTransition(
turns: turnsTween.animate(_controller),
...
Sample result and code to reproduce:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
/// AnimationControllers can be created with `vsync: this` because of TickerProviderStateMixin.
class _MyStatefulWidgetState extends State<MyStatefulWidget>
with TickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 4),
vsync: this,
)..repeat();
final Tween<double> turnsTween = Tween<double>(
begin: 1,
end: 0,
);
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RotationTransition(
turns: turnsTween.animate(_controller),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: FlutterLogo(size: 150.0),
),
),
),
);
}
}
You can add in an AnimationBuilder and Animation object and set the end Tween property to negative.
Also, It looked like you were attempting to have the widget reverse rotation upon completion in a cycle? If so, I added in the code for that too if it helps :)
For example:
#override
void initState() {
_controller =
AnimationController(vsync: this, duration: Duration(seconds: 3))
//To have the widget change rotation direction upon completion
..addStatusListener((status) {
if(status == AnimationStatus.completed)
_controller.reverse();
if(status == AnimationStatus.dismissed){
_controller.forward();
}
});
_animTurn = Tween<double>(begin: 0.0, end: -1.0).animate(_controller);
_controller.forward();
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return
RotationTransition(
turns: _animTurn,
child: Icon(Icons.settings_sharp,size: 100,),
alignment: Alignment.center,
);
});
}
}
Related
There's an interactive example in the flutter docs with slide transition. The animations looks great but I can't stop the animation from constantly repeating. There's a repeat method used on the AnimationController that seems to control the looping of the animation. But I can't see where you can for instance run the animation twice?
Here is the code for connivence ..
/ The following code implements the [SlideTransition] as seen in the video
// above:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatefulWidget(),
),
),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget>
with SingleTickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
late final Animation<Offset> _offsetAnimation = Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.5, 0.0),
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.elasticIn,
));
#override
void dispose() {
super.dispose();
_controller.dispose();
}
#override
Widget build(BuildContext context) {
return SlideTransition(
position: _offsetAnimation,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: FlutterLogo(size: 150.0),
),
);
}
}
Use forward and wait for it to resolve and then call reverse
#override
void initState() {
super.initState();
repeatOnce();
}
void repeatOnce() async {
await _controller.forward();
await _controller.reverse();
}
The Full example
/// Flutter code sample for SlideTransition
// The following code implements the [SlideTransition] as seen in the video
// above:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatefulWidget(),
),
),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget>
with SingleTickerProviderStateMixin {
late final AnimationController _controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
late final Animation<Offset> _offsetAnimation = Tween<Offset>(
begin: Offset.zero,
end: const Offset(1.5, 0.0),
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.elasticIn,
));
#override
void initState() {
super.initState();
repeatOnce();
}
void repeatOnce() async {
await _controller.forward();
await _controller.reverse();
}
#override
void dispose() {
super.dispose();
_controller.dispose();
}
#override
Widget build(BuildContext context) {
return SlideTransition(
position: _offsetAnimation,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: FlutterLogo(size: 150.0),
),
);
}
}
I'm shaking a widget using the below code, but the effect is once,
how do I keep it running in a loop at timed intervals. I believe it can be done by changing the key but it's a final and can't be changed.
import 'package:flutter/material.dart';
#immutable
class ShakeWidget extends StatelessWidget {
final Duration duration;
final double deltaX;
final Widget child;
final Curve curve;
const ShakeWidget({
Key key,
this.duration = const Duration(milliseconds: 500),
this.deltaX = 20,
this.curve = Curves.bounceOut,
this.child,
}) : super(key: key);
/// convert 0-1 to 0-1-0
double shake(double animation) =>
2 * (0.5 - (0.5 - curve.transform(animation)).abs());
#override
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
key: key,
tween: Tween(begin: 0.0, end: 1.0),
duration: duration,
builder: (context, animation, child) => Transform.translate(
offset: Offset(deltaX * shake(animation), 0),
child: child,
),
child: child,
);
}
}
You need to use AnimationController
And call repeat when the controller is completed
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: Scaffold(
body: SafeArea(
child: ShakeWidget(
child: Text('Hello world'),
),
),
),
);
}
}
class ShakeWidget extends StatefulWidget {
const ShakeWidget({
Key key,
this.duration = const Duration(milliseconds: 500),
this.deltaX = 20,
this.curve = Curves.bounceOut,
#required this.child,
}) : super(key: key);
final Duration duration;
final double deltaX;
final Widget child;
final Curve curve;
#override
_ShakeWidgetState createState() => _ShakeWidgetState();
}
class _ShakeWidgetState extends State<ShakeWidget>
with SingleTickerProviderStateMixin {
AnimationController controller;
#override
void initState() {
super.initState();
controller = AnimationController(
duration: widget.duration,
vsync: this,
)
..forward()
..addListener(() {
if (controller.isCompleted) {
controller.repeat();
}
});
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
/// convert 0-1 to 0-1-0
double shake(double value) =>
2 * (0.5 - (0.5 - widget.curve.transform(value)).abs());
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: controller,
builder: (context, child) => Transform.translate(
offset: Offset(widget.deltaX * shake(controller.value), 0),
child: child,
),
child: widget.child,
);
}
}
Use an AnimationController, like so:
AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
)..repeat();
The simple_animations package comes with the LoopAnimation widget which is meant for exactly this. This also means you don't have to create an AnimationController so the code's a lot cleaner.
LoopAnimation(
builder: (context, child, double value) {
return Transform.rotate(
angle: pi * value,
child: const Icon(Icons.notifications),
);
},
duration: const Duration(seconds: 1),
tween: Tween<double>(begin: 0, end: 2),
);
If you want to run an animation forward and backward continuously to get a yo-yo effect, you can use the MirrorAnimation widget instead.
Here is the repeating animation sample, from start → end then from end ← start
#override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: widget.duration);
_animation = widget.tween.animate(
CurvedAnimation(parent: _animationController, curve: Curves.easeIn));
_animationController.forward();
// The looping is done via listener.
_animationController.addListener(() {
if (_animationController.isCompleted) {
_animationController.reverse();
}
if(_animationController.isDismissed){
_animationController.forward();
}
});
}
Don't forget to call _animationController.dispose() in the state's dispose() method.
I am trying to animate an image (or logo) from center of the screen to top of the screen.
For that, I had a look at SlideTransition. It works, but for portrait orientation only. When the device is rotated, the image goes outside of the screen. (maybe I did not understand the Offset property correctly!) If I make it work for horizontal, the output of the portrait gets changed.
Let me show you the output:
Portrait:
Before animation
After animation (As wanted)
Horizontal:
Before animation
After animation (Problem HERE)
So, as you can see, in horizontal mode, the Logo goes out of the screen.
Here is the code:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SlideTransition Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<Offset> _offsetAnimation;
#override
void initState() {
_controller = AnimationController(vsync: this, duration: Duration(milliseconds: 300));
_offsetAnimation = _controller
.drive(CurveTween(curve: Curves.easeInOut))
.drive(Tween<Offset>(begin: Offset(0.0, 0.0), end: Offset(0.0, -1.0)));
super.initState();
}
#override
void dispose() {
_controller?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SlideTransition Demo'),
),
body: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: SlideTransition(
position: _offsetAnimation,
child: FlutterLogo(
size: 200,
),
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_controller.status == AnimationStatus.completed) {
_controller.reverse();
} else if (_controller.status == AnimationStatus.dismissed) {
_controller.forward();
}
},
child: Icon(Icons.play_arrow),
),
);
}
}
The SlideTransition does the fractional translation. And this translation depends on the size of the child of the SlideTransition widget.
Tween(begin: Offset(0.0, 0.0), end: Offset(0.0, -1.0))
This tween translates(moves) the FlutterLogo in y-axis for 200(height of the FlutterLogo widget)
Tween(begin: Offset(0.0, 0.0), end: Offset(0.0, -0.5))
This tween translates(moves) the FlutterLogo in y-axis for 100(half-height of the FlutterLogo widget)
If you just want to animate the image from center to topCenter, then you can use AlignTransition.
Example:
class FirstPage extends StatefulWidget {
#override
FirstPageState createState() => FirstPageState();
}
class FirstPageState extends State<FirstPage> with TickerProviderStateMixin {
AnimationController _animationController;
AlignmentGeometryTween _tween;
#override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 3),
);
_tween = AlignmentGeometryTween(
begin: Alignment.center,
end: Alignment.topCenter,
);
}
TickerFuture _play() {
_animationController.reset();
return _animationController.animateTo(
1.0,
curve: Curves.easeInOut,
);
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: Text("Demo")),
body: AlignTransition(
alignment: _tween.animate(_animationController),
child: FlutterLogo(
size: 200,
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.play_arrow),
onPressed: _play,
),
),
);
}
}
Demo: DartPad
You can copy paste run full code below
You can use OrientationBuilder and modify Offset to what you need
code snippet
body: OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.portrait) {
_offsetAnimation = _controller
.drive(CurveTween(curve: Curves.easeInOut))
.drive(Tween<Offset>(
begin: Offset(0.0, 0.0), end: Offset(0.0, -1.0)));
} else {
_offsetAnimation = _controller
.drive(CurveTween(curve: Curves.easeInOut))
.drive(Tween<Offset>(
begin: Offset(0.0, 0.0), end: Offset(-1.0, 0.0)));
}
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SlideTransition Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<Offset> _offsetAnimation;
Animation<Offset> _offsetAnimationLandscape;
#override
void initState() {
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 300));
super.initState();
}
#override
void dispose() {
_controller?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SlideTransition Demo'),
),
body: OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.portrait) {
_offsetAnimation = _controller
.drive(CurveTween(curve: Curves.easeInOut))
.drive(Tween<Offset>(
begin: Offset(0.0, 0.0), end: Offset(0.0, -1.0)));
} else {
_offsetAnimation = _controller
.drive(CurveTween(curve: Curves.easeInOut))
.drive(Tween<Offset>(
begin: Offset(0.0, 0.0), end: Offset(-1.0, 0.0)));
}
return Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: SlideTransition(
position: _offsetAnimation,
child: FlutterLogo(
size: 200,
),
),
),
],
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_controller.status == AnimationStatus.completed) {
_controller.reverse();
} else if (_controller.status == AnimationStatus.dismissed) {
_controller.forward();
}
},
child: Icon(Icons.play_arrow),
),
);
}
}
I made a simple class for animating a widget into the screen:
class CustomSlideAnimation extends StatefulWidget {
static const String FROM_LEFT = 'FROM_LEFT';
static const String FROM_RIGHT = 'FROM_RIGHT';
final String from;
final Widget child;
const CustomSlideAnimation(
{Key key, this.from = FROM_LEFT, #required this.child})
: super(key: key);
#override
_CustomSlideAnimationState createState() => _CustomSlideAnimationState();
}
class _CustomSlideAnimationState extends State<CustomSlideAnimation>
with SingleTickerProviderStateMixin {
Animation<Offset> _offsetAnimation;
AnimationController _animationController;
#override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 300));
_offsetAnimation = widget.from == CustomSlideAnimation.FROM_LEFT
? Tween<Offset>(
begin: Offset(-1.0, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
curve: Curves.linear,
parent: _animationController,
))
: Tween<Offset>(
begin: Offset(1.0, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
curve: Curves.linear,
parent: _animationController,
));
_animationController.forward();
}
#override
void dispose() {
super.dispose();
_animationController.dispose();
}
#override
Widget build(BuildContext context) {
return SlideTransition(
position: _offsetAnimation,
child: widget.child,
);
}
}
And a simple app to demonstrate the problem:
void main() => runApp(Test());
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
bool widget1 = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: widget1
? CustomSlideAnimation(
child: InkWell(
child: Text('widget1'),
onTap: () {
setState(() {
widget1 = false;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
)
: CustomSlideAnimation(
child: InkWell(
child: Text('widget2'),
onTap: () {
setState(() {
widget1 = true;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
),
),
),
);
}
}
When I start the app for first time the Text widget as expected slides in to the screen,
but then I tap it and thus calling setState() the second Text widget just appears suddenly into the screen and no slide transition happens.
I printed the times when build get called in all the classes and I see that setState() is triggering builds in Test and CustomSlideTransition classes but not triggering initState() in the CustomSlideTransition.
EDIT for more clarification: even putting controller.forward() inside the build() method didn't work.
So what am I missing?
You just need to add a UniqueKey() to every CustomSlideAnimation() to tell flutter to treat them like different widgets.
void main() => runApp(Test());
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
bool widget1 = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: widget1
? CustomSlideAnimation(
key: UniqueKey(),
child: InkWell(
child: Text('widget1'),
onTap: () {
setState(() {
widget1 = false;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
)
: CustomSlideAnimation(
key: UniqueKey(),
child: InkWell(
child: Text('widget2'),
onTap: () {
setState(() {
widget1 = true;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
),
),
),
);
}
}
Also, keep controller.forward() inside initState()
I figured it out, the reason is in the keys and widget trees as explained in this video.
When the setState was called without CustomSlideTransition having a unique key, then the framework did not recreate the State object of this class again and it instead used the State object of the previous widget which had the AnimationStatus as completed
But now with keys each time the framework creates a new State object and calls initState() where the controller is reset and the animation starts normally.
I also found a workaround but I don't know if it is as efficient as the "keys" solution:
Without adding a key to the CustomSlideTransition widget,I can, in the build() method of this widget, do these two commands:
_animationController.reset();
_animationController.forward();
and remove the call to _animationController.forward(); in initState().
in this sample code i want to make container with for example 100.0 size of height and move that into screen by animation to show that, like with simple bottom sheet, this sample code work but its not what i want to have
problem is moving that into screen with size of container witch that
is 100.0 on our sample
start animation from bottom height of container into screen
for example:
in this sample code animate move container to top of screen not size of that
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Page(),
);
}
}
class Page extends StatefulWidget {
#override
State<StatefulWidget> createState() => _PageState();
}
class _PageState extends State<Page> with SingleTickerProviderStateMixin {
Tween<Offset> tween = Tween<Offset>(
begin: Offset(0.0, 10000.0),
end: Offset(0.0, 0.0),
);
Animation<Offset> animation;
AnimationController animationController;
GlobalKey _widgetKey = GlobalKey();
#override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
animation = tween.animate(animationController);
Future<void>.delayed(Duration(seconds: 1), () {
final Size screenSize = MediaQuery.of(context).size;
final RenderBox widgetRenderBox =
_widgetKey.currentContext.findRenderObject();
final Size widgetSize = widgetRenderBox.size;
final double offset = (screenSize.height / 2 / widgetSize.height).ceilToDouble();
tween = Tween<Offset>(
begin: Offset(0.0, offset),
end: Offset(0.0, 0.0),
);
animation = tween.animate(animationController);
this.setState((){
animationController.forward();
});
});
}
#override
void dispose() {
animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('ddddddd'),),
body: Stack(
alignment: Alignment.center,
fit: StackFit.loose,
children: <Widget>[
SlideTransition(
position: animation,
child: Container(
key: _widgetKey,
height:100.0,
width: 300.0,
color:Colors.indigo,
child:Center(
child:Text('ddddddddddddd'),
)
)
),
],
),
);
}
}
I hope I did not misunderstood your question.
The Stack should have the size of the whole screen. Wrap it with SizedBox for example.
No need to center the text. You should rather align it inside the Container itself.
The container should have the width of the screen.
The height of the container is not necessary and therefore we don't need to figure it out.
This works for me:
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: Page(),
);
}
}
class Page extends StatefulWidget {
const Page({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => _PageState();
}
class _PageState extends State<Page> with SingleTickerProviderStateMixin {
late final AnimationController _animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
late final Animation<Offset> _animation =
Tween<Offset>(begin: const Offset(0, 1), end: const Offset(0, 0))
.animate(_animationController);
#override
void initState() {
super.initState();
delayedStart();
}
void delayedStart() async {
await Future.delayed(const Duration(seconds: 2), () {
_animationController.forward();
});
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ddddddd'),
),
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Stack(
alignment: Alignment.bottomCenter,
fit: StackFit.loose,
children: <Widget>[
SlideTransition(
position: _animation,
child: Container(
alignment: Alignment.center,
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.indigo,
child: const Text('ddddddddddddd')
)
),
],
),
),
);
}
}