Flutter: can´t open the CustomPainter class - flutter

I have a problem to implement the CustomPainter class, don't know my mistake in every single tutorial they did the same like me hope someone know the solution.
class _MyHomepageState extends State<MyHomepage> {
var _name;
final nameCon = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'App',
style: TextStyle(fontWeight: FontWeight.w900),
),
backgroundColor: Colors.brown[500],
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: nameCon,
decoration: InputDecoration(hintText: "Name"),
),
RaisedButton(
onPressed: () {
setState(() {
_name = nameCon.text;
});
},
child: Text("Los"),
),
Text("hier $_name "),
Expanded(
child: LayoutBuilder(
builder: (_, constraints) => Container(
width: constraints.widthConstraints().maxWidth,
height: constraints.heightConstraints().maxHeight,
color: Colors.yellow,
child: CustomPaint(painter: Thermometer()),
),
),
),
],
),
),
),
);
}
}
class Thermometer extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.brown
..style = PaintingStyle.stroke
..style=PaintingStyle.fill
..strokeWidth = 4;
canvas.drawRRect(
RRect.fromRectAndRadius(Rect.fromLTWH(-140, -60, 40, 290),
Radius.circular(20)),
paint,);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false ;
}

You can copy paste run full code below
please change left from -140 to 0 or other value
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(0, -60, 40, 290), Radius.circular(20)),
paint,
);
working demo
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: '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> {
var _name;
final nameCon = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'App',
style: TextStyle(fontWeight: FontWeight.w900),
),
backgroundColor: Colors.brown[500],
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: nameCon,
decoration: InputDecoration(hintText: "Name"),
),
RaisedButton(
onPressed: () {
setState(() {
_name = nameCon.text;
});
},
child: Text("Los"),
),
Text("hier $_name "),
Expanded(
child: LayoutBuilder(
builder: (_, constraints) => Container(
width: constraints.widthConstraints().maxWidth,
height: constraints.heightConstraints().maxHeight,
color: Colors.yellow,
child: CustomPaint(painter: Thermometer()),
),
),
),
],
),
),
),
);
}
}
class Thermometer extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.brown
..style = PaintingStyle.stroke
..style = PaintingStyle.fill
..strokeWidth = 4;
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(0, -60, 40, 290), Radius.circular(20)),
paint,
);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}

Related

how to create ListView like given image

Blockquote
how to create list view like this how to create this type layout in flutter
you can copy the whole code in below
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late PageController controller;
double page = 0.0;
#override
void initState() {
super.initState();
controller = PageController(viewportFraction: 0.5)
..addListener(() {
setState(() {
page = controller.page!;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade100,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(26),
color: Colors.white,
),
child: Column(children: [
Text(
'head widgets',
style: TextStyle(
fontSize: 12,
color: Colors.grey.shade500,
),
),
Expanded(
child: PageView.builder(
controller: controller,
itemCount: pages.length,
itemBuilder: (context, index) {
if (index == page) {
return Transform.scale(
scale: 1,
child: pages[index],
);
} else if (index < page) {
return Transform.scale(
scale: max(1 - (page - index), 0.75),
child: pages[index],
);
} else {
return Transform.scale(
scale: max(1 - (index - page), 0.75),
child: pages[index],
);
}
},
),
),
Text(
'indicator',
style: TextStyle(fontSize: 12),
)
]),
),
),
);
}
List<Widget> pages = [
FlutterLogo(
size: 100,
),
FlutterLogo(
size: 100,
),
FlutterLogo(
size: 100,
),
];
}
and the result

ScaleTransition looks like as it was sliding from right to left

I'm trying to make a widget that scale down and reappears at the different side, I was expecting it to scale down and scale up regardless of its alignment. But when I try, it looks like as it was sliding from the right to the left.
Tried removing the ListTile from the _buildRightAlignedListTile and uses the text directly and the ValueKey assigned to it but it still looks the same.
Is there any way to prevent this?
H̶e̶r̶e̶ ̶i̶s̶ ̶t̶h̶e̶ ̶s̶c̶r̶i̶p̶t̶ ̶y̶o̶u̶ ̶c̶a̶n̶ ̶t̶r̶y̶ ̶t̶o̶ ̶r̶u̶n̶ ̶i̶n̶ ̶[̶D̶a̶r̶t̶P̶a̶d̶]̶(̶h̶t̶t̶p̶s̶:̶/̶/̶d̶a̶r̶t̶p̶a̶d̶.̶d̶e̶v̶)̶,̶ ̶p̶l̶e̶a̶s̶e̶ ̶h̶a̶v̶e̶ ̶a̶ ̶l̶o̶o̶k̶.̶
EDIT
Finally found a way to share it, please use this DartPad link to reproduce the issue.
You can also copy and paste the script below just in case the link is dead. It was made directly from the dartpad.
EDIT 2
I apologize if my explanation is confusing, I'm having trouble trying to find the right words to explain it. I'm not a native speaker.
I want the right aligned widget to stay on the right and scale down in place until it disappear completely. And then the left aligned widget to scale up on the left, instead of scaling up from the middle to the left.
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _active = false;
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: SwitchingWidget(active: _active),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggle,
child: const Icon(Icons.check)
),
),
);
}
void _toggle() {
setState(() {
_active = !_active;
});
}
}
class SwitchingWidget extends StatefulWidget {
const SwitchingWidget({super.key, this.active = false});
final bool active;
#override
State<SwitchingWidget> createState() => _SwitchingWidgetState();
}
class _SwitchingWidgetState extends State<SwitchingWidget> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
transitionBuilder: (child, animation) {
return ScaleTransition(scale: animation, child: child);
},
child: widget.active
? _buildLeftAlignedListTile()
: _buildRightAlignedListTile(),
),
);
}
Widget _buildLeftAlignedListTile() {
return const ListTile(
key: ValueKey(1),
leading: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
),
title: Text(
'Left aligned',
style: TextStyle(color: Colors.white),
),
);
}
Widget _buildRightAlignedListTile() {
return const ListTile(
key: ValueKey(2),
title: Text(
'Right aligned',
textAlign: TextAlign.right,
style: TextStyle(color: Colors.white),
),
);
}
}
Found a solution to this while tinkering around with another stuff. The solution is to use separate AnimatedSwitcher for each widget I want to animate instead of using one and placing it directly with a conditional statement.
The script above has slightly modified and it works perfectly just like what I wanted. You can also copy and paste to run it on the DartPad since it was made from there to try it out.
Please let me know if there is a better approach!
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _active = false;
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: SwitchingWidget(active: _active),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggle,
child: const Icon(Icons.check)
),
),
);
}
void _toggle() {
setState(() {
_active = !_active;
});
}
}
class SwitchingWidget extends StatefulWidget {
const SwitchingWidget({super.key, this.active = false});
final bool active;
#override
State<SwitchingWidget> createState() => _SwitchingWidgetState();
}
class _SwitchingWidgetState extends State<SwitchingWidget> {
final scaleDuration = const Duration(milliseconds: 200);
Widget transitionBuilder(child, animation) {
return ScaleTransition(child: child, scale: animation);
}
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AnimatedSwitcher(
duration: scaleDuration,
transitionBuilder: transitionBuilder,
child: widget.active
? const SizedBox()
: _buildLeftAlignedWidget(),
),
AnimatedSwitcher(
duration: scaleDuration,
transitionBuilder: transitionBuilder,
child: widget.active
? _buildRightAlignedWidget()
: const SizedBox(),
),
],
),
);
}
Widget _buildLeftAlignedWidget() {
return Row(
key: const ValueKey(1),
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(right: 16),
width: 20,
height: 20,
child: const CircularProgressIndicator(color: Colors.white, strokeWidth: 2),
),
const Text(
'Left aligned',
style: TextStyle(color: Colors.white),
),
],
);
}
Widget _buildRightAlignedWidget() {
return const Text(
key: ValueKey(2),
'Right aligned',
textAlign: TextAlign.right,
style: TextStyle(color: Colors.white),
);
}
}

How can I scroll down and focus to a specific widget in flutter?

I am implementing a tutorial of app using https://pub.dev/packages/tutorial_coach_mark . This marked button of beyond the view. So when I need to target this button, I need to scroll/focus this specific part. But I can not find any solution. Can anyone help me with that please?
One Idea is to , Make one Listview with all your widgets . then
Use this :
scroll_to_index: ^2.1.1
Example:
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.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: 'Scroll To Index Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Scroll To Index Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const maxCount = 100;
static const double maxHeight = 1000;
final random = math.Random();
final scrollDirection = Axis.vertical;
late AutoScrollController controller;
late List<List<int>> randomList;
#override
void initState() {
super.initState();
controller = AutoScrollController(
viewportBoundaryGetter: () =>
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
axis: scrollDirection);
randomList = List.generate(maxCount,
(index) => <int>[index, (maxHeight * random.nextDouble()).toInt()]);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [
IconButton(
onPressed: () {
setState(() => counter = 0);
_scrollToCounter();
},
icon: Text('First'),
),
IconButton(
onPressed: () {
setState(() => counter = maxCount - 1);
_scrollToCounter();
},
icon: Text('Last'),
)
],
),
body: ListView(
scrollDirection: scrollDirection,
controller: controller,
children: randomList.map<Widget>((data) {
return Padding(
padding: EdgeInsets.all(8),
child: _getRow(data[0], math.max(data[1].toDouble(), 50.0)),
);
}).toList(),
),
floatingActionButton: FloatingActionButton(
onPressed: _nextCounter,
tooltip: 'Increment',
child: Text(counter.toString()),
),
);
}
int counter = -1;
Future _nextCounter() {
setState(() => counter = (counter + 1) % maxCount);
return _scrollToCounter();
}
Future _scrollToCounter() async {
await controller.scrollToIndex(counter,
preferPosition: AutoScrollPosition.begin);
controller.highlight(counter);
}
Widget _getRow(int index, double height) {
return _wrapScrollTag(
index: index,
child: Container(
padding: EdgeInsets.all(8),
alignment: Alignment.topCenter,
height: height,
decoration: BoxDecoration(
border: Border.all(color: Colors.lightBlue, width: 4),
borderRadius: BorderRadius.circular(12)),
child: Text('index: $index, height: $height'),
));
}
Widget _wrapScrollTag({required int index, required Widget child}) =>
AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: child,
highlightColor: Colors.black.withOpacity(0.1),
);
}
This will work Perfectly
final dataKey = new GlobalKey();
SingleChildScrollView(
child: Column(
children: [
otherwidgets(),
otherwidgets(),
Container(
key: controller.dataKey,
child: helpPart(context),
),
otherwidgets(),
otherwidgets(),
],
),
on action: Scrollable.ensureVisible(dataKey.currentContext!);
This worked for me!

Adding a toggled button/icon to App in flutter

Looking for a way to implement a button that can be toggled back and forth between favorites and history. Is there a way to do this in flutter.
You can try using a custom widget like this one below:
toggle_button.dart
import 'package:flutter/material.dart';
class ToggleButton extends StatefulWidget {
final double width;
final double height;
final String leftDescription;
final String rightDescription;
final Color toggleColor;
final Color toggleBackgroundColor;
final Color toggleBorderColor;
final Color inactiveTextColor;
final Color activeTextColor;
final double _leftToggleAlign = -1;
final double _rightToggleAlign = 1;
final VoidCallback onLeftToggleActive;
final VoidCallback onRightToggleActive;
const ToggleButton(
{Key? key,
required this.width,
required this.height,
required this.toggleBackgroundColor,
required this.toggleBorderColor,
required this.toggleColor,
required this.activeTextColor,
required this.inactiveTextColor,
required this.leftDescription,
required this.rightDescription,
required this.onLeftToggleActive,
required this.onRightToggleActive})
: super(key: key);
#override
_ToggleButtonState createState() => _ToggleButtonState();
}
class _ToggleButtonState extends State<ToggleButton> {
double _toggleXAlign = -1;
late Color _leftDescriptionColor;
late Color _rightDescriptionColor;
#override
void initState() {
super.initState();
_leftDescriptionColor = widget.activeTextColor;
_rightDescriptionColor = widget.inactiveTextColor;
}
#override
Widget build(BuildContext context) {
return Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
color: widget.toggleBackgroundColor,
borderRadius: BorderRadius.all(
Radius.circular(50.0),
),
border: Border.all(color: widget.toggleBorderColor),
),
child: Stack(
children: [
AnimatedAlign(
alignment: Alignment(_toggleXAlign, 0),
duration: Duration(milliseconds: 300),
child: Container(
width: widget.width * 0.5,
height: widget.height,
decoration: BoxDecoration(
color: widget.toggleColor,
borderRadius: BorderRadius.all(
Radius.circular(50.0),
),
),
),
),
GestureDetector(
onTap: () {
setState(
() {
_toggleXAlign = widget._rightToggleAlign;
_leftDescriptionColor = widget.inactiveTextColor;
_rightDescriptionColor = widget.activeTextColor;
},
);
widget.onRightToggleActive();
},
child: Align(
alignment: Alignment(-1, 0),
child: Container(
width: widget.width * 0.5,
color: Colors.transparent,
alignment: Alignment.center,
child: Text(
widget.leftDescription,
style: TextStyle(
color: _leftDescriptionColor,
fontWeight: FontWeight.bold),
),
),
),
),
GestureDetector(
onTap: () {
setState(
() {
_toggleXAlign = widget._leftToggleAlign;
_leftDescriptionColor = widget.activeTextColor;
_rightDescriptionColor = widget.inactiveTextColor;
},
);
widget.onLeftToggleActive();
},
child: Align(
alignment: Alignment(1, 0),
child: Container(
width: widget.width * 0.5,
color: Colors.transparent,
alignment: Alignment.center,
child: Text(
widget.rightDescription,
style: TextStyle(
color: _rightDescriptionColor,
fontWeight: FontWeight.bold),
),
),
),
),
],
),
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:stackovfl_70777885/toggle_button.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
padding: EdgeInsets.all(10.0),
child: ToggleButton(
width: 300.0,
height: 60.0,
toggleBackgroundColor: Colors.white,
toggleBorderColor: (Colors.grey[350])!,
toggleColor: (Colors.indigo[900])!,
activeTextColor: Colors.white,
inactiveTextColor: Colors.grey,
leftDescription: 'FAVORITES',
rightDescription: 'HISTORY',
onLeftToggleActive: () {
print('left toggle activated');
},
onRightToggleActive: () {
print('right toggle activated');
},
),
),
);
}
}
This should result in the following:
The onLeftToggleActive(): () {} and onRightToggleActive() {} in main are triggered depending on where the slider moves.

Flutter hero animation between widgets not screens

Hero animation is the best for navigating between screen, but I need same animation between widgets. Like one card moving another place for example: Product Card moves to shoppingcart and something else. Thanks for answers!
Try this one, add_to_cart_animation:
import 'package:add_to_cart_animation/add_to_cart_animation.dart';
import 'package:add_to_cart_animation/add_to_cart_icon.dart';
import 'package:flutter/material.dart';
import 'list_item.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: 'Add To Cart Animation',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Add To Cart Animation'),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// We can detech the location of the card by this GlobalKey<CartIconKey>
GlobalKey<CartIconKey> gkCart = GlobalKey<CartIconKey>();
late Function(GlobalKey) runAddToCardAnimation;
var _cartQuantityItems = 0;
#override
Widget build(BuildContext context) {
return AddToCartAnimation(
// To send the library the location of the Cart icon
gkCart: gkCart,
rotation: true,
dragToCardCurve: Curves.easeIn,
dragToCardDuration: const Duration(milliseconds: 1000),
previewCurve: Curves.linearToEaseOut,
previewDuration: const Duration(milliseconds: 500),
previewHeight: 30,
previewWidth: 30,
opacity: 0.85,
initiaJump: false,
receiveCreateAddToCardAnimationMethod: (addToCardAnimationMethod) {
// You can run the animation by addToCardAnimationMethod, just pass trough the the global key of the image as parameter
this.runAddToCardAnimation = addToCardAnimationMethod;
},
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
centerTitle: false,
actions: [
// Improvement/Suggestion 4.4 -> Adding 'clear-cart-button'
IconButton(
icon: Icon(Icons.cleaning_services),
onPressed: () {
_cartQuantityItems = 0;
gkCart.currentState!.runClearCartAnimation();
},
),
SizedBox(width: 16),
AddToCartIcon(
key: gkCart,
icon: Icon(Icons.shopping_cart),
colorBadge: Colors.red,
),
SizedBox(
width: 16,
)
],
),
body: ListView(
children: [
AppListItem(onClick: listClick, index: 1),
AppListItem(onClick: listClick, index: 2),
AppListItem(onClick: listClick, index: 3),
AppListItem(onClick: listClick, index: 4),
AppListItem(onClick: listClick, index: 5),
AppListItem(onClick: listClick, index: 6),
AppListItem(onClick: listClick, index: 7),
],
),
),
);
}
// Improvement/Suggestion 4.4 -> Running AddTOCartAnimation BEFORE runCArtAnimation
void listClick(GlobalKey gkImageContainer) async {
await runAddToCardAnimation(gkImageContainer);
await gkCart.currentState!.runCartAnimation((++_cartQuantityItems).toString());
}
}
OR
[not null safety]
this is a sample of add to cart, add_cart_parabola:
import 'dart:ui';
import 'package:add_cart_parabola/add_cart_parabola.dart';
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();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
GlobalKey floatKey = GlobalKey();
GlobalKey rootKey = GlobalKey();
Offset floatOffset ;
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
RenderBox renderBox = floatKey.currentContext.findRenderObject();
floatOffset = renderBox.localToGlobal(Offset.zero);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
key: rootKey,
width: double.infinity,
height: double.infinity,
color: Colors.grey,
child: ListView(
children: List.generate(40, (index){
return generateItem(index);
}).toList(),
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.yellow,
key: floatKey,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget generateItem(int index){
Text text = Text("item $index",style: TextStyle(fontSize:
25),);
Offset temp;
return GestureDetector(
onPanDown: (details){
temp = new Offset(details.globalPosition.dx, details.globalPosition
.dy);
},
onTap: (){
Function callback ;
setState(() {
OverlayEntry entry = OverlayEntry(
builder: (ctx){
return ParabolaAnimateWidget(rootKey,temp,floatOffset,
Icon(Icons.cancel,color: Colors.greenAccent,),callback,);
}
);
callback = (status){
if(status == AnimationStatus.completed){
entry?.remove();
}
};
Overlay.of(rootKey.currentContext).insert(entry);
});
},
child: Container(
color: Colors.orange,
child: text,
),
);
}
}
For animating widget in the same screen you can use AnimatedPositioned widget see the below code
import 'dart:math';
import 'package:flutter/material.dart';
class AnimatedPositionedDemo extends StatefulWidget {
const AnimatedPositionedDemo({Key? key}) : super(key: key);
static String routeName = 'animated_positioned';
#override
_AnimatedPositionedDemoState createState() => _AnimatedPositionedDemoState();
}
class _AnimatedPositionedDemoState extends State<AnimatedPositionedDemo> {
late double topPosition;
late double leftPosition;
double generateTopPosition(double top) => Random().nextDouble() * top;
double generateLeftPosition(double left) => Random().nextDouble() * left;
#override
void initState() {
super.initState();
topPosition = generateTopPosition(30);
leftPosition = generateLeftPosition(30);
}
void changePosition(double top, double left) {
setState(() {
topPosition = generateTopPosition(top);
leftPosition = generateLeftPosition(left);
});
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final appBar = AppBar(title: const Text('AnimatedPositioned'));
final topPadding = MediaQuery.of(context).padding.top;
// AnimatedPositioned animates changes to a widget's position within a Stack
return Scaffold(
appBar: appBar,
body: SizedBox(
height: size.height,
width: size.width,
child: Stack(
children: [
AnimatedPositioned(
top: topPosition,
left: leftPosition,
duration: const Duration(seconds: 1),
child: InkWell(
onTap: () => changePosition(
size.height -
(appBar.preferredSize.height + topPadding + 50),
size.width - 150),
child: Container(
alignment: Alignment.center,
width: 150,
height: 50,
child: Text(
'Click Me',
style: TextStyle(
color:
Theme.of(context).buttonTheme.colorScheme!.onPrimary,
),
),
color: Theme.of(context).primaryColor,
),
),
),
],
),
),
);
}
}
I hope it works for you
For Animated widgets, flutter team has provided a video on youtube here
And you can read all about them on their website here