I have class called A.dart in that I am usnign Interprogressbar as below
new Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: IntervalProgressBar(
direction: IntervalProgressDirection.horizontal,
max: count,
progress: count1,
intervalSize: 2,
size: Size(600, 10),
highlightColor: Colors.pink,
defaultColor: Colors.grey,
intervalColor: Colors.transparent,
intervalHighlightColor: Colors.transparent,
reverse: false,
radius: 0)),
Once the user clicks a button I am navigating to another class from A.dart to a class called B.dart. Once use completes process in class B.dart I ll pop the class B.dart. Again A.dart will be visible for the user. So my question us how can I restart the IntervalProgressBar with the updated value once user comes from B.dart to A,dart.
You can copy paste run full code below
You can await Navigator.push then call setState
void _gotoB() async {
String parameter = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => RouteB()),
);
setState(() {
count1 = int.tryParse(parameter);
});
}
...
RaisedButton(
child: Text('Go back'),
onPressed: () {
Navigator.pop(context, _textEditingController.text);
},
),
working demo
full code
import 'package:flutter/material.dart';
import 'package:intervalprogressbar/intervalprogressbar.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#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 count = 10;
int count1 = 3;
void _gotoB() async {
String parameter = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => RouteB()),
);
setState(() {
count1 = int.tryParse(parameter);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: IntervalProgressBar(
direction: IntervalProgressDirection.horizontal,
max: count,
progress: count1,
intervalSize: 2,
size: Size(600, 10),
highlightColor: Colors.pink,
defaultColor: Colors.grey,
intervalColor: Colors.transparent,
intervalHighlightColor: Colors.transparent,
reverse: false,
radius: 0)),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _gotoB,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class RouteB extends StatefulWidget {
#override
_RouteBState createState() => _RouteBState();
}
class _RouteBState extends State<RouteB> {
TextEditingController _textEditingController = TextEditingController();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
TextField(
controller: _textEditingController,
),
RaisedButton(
child: Text('Go back'),
onPressed: () {
Navigator.pop(context, _textEditingController.text);
},
),
],
)),
);
}
}
Related
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!
I have implemented BlocConsumer for listening to the stream, which will trigger the snack bar widget depending on the state event.
The snack bar is getting triggered three times on a single increment event on the third screen and two times on the second screen. How to make it show once every click on both screens I am using the bloc, flutter_bloc package, any suggestion or direction will be helpful, thank you.
class SecondScreen extends StatefulWidget {
const SecondScreen({Key? key, required this.title, required this.color})
: super(key: key);
final String title;
final Color color;
#override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.title.toString(),
),
backgroundColor: widget.color,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('SECOND PAGE', style: Theme.of(context).textTheme.headline4),
const SizedBox(height: 40.0),
const Text(
'You have clicked this many times',
),
const SizedBox(height: 10.00),
BlocConsumer<CounterCubit, CounterState>(
listener: (context, state) {
// show a snackbar everytime the state changes
// this block of code is listening to every event triggering in the state
if (state.wasIncremented == true) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Incremented'),
duration: Duration(milliseconds: 100),
),
);
} else if (state.wasIncremented == false) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Decremented'),
duration: Duration(milliseconds: 100),
),
);
}
},
builder: (context, state) {
return Text(
state.counterValue.toString(),
style: Theme.of(context).textTheme.headline4,
);
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () {
// TO DO
BlocProvider.of<CounterCubit>(context).decrement();
},
child: const Icon(Icons.remove),
heroTag: const Text('btn1'),
),
FloatingActionButton(
onPressed: () {
// TO DO
BlocProvider.of<CounterCubit>(context).increment();
},
child: const Icon(Icons.add),
heroTag: const Text('btn2')),
],
),
const SizedBox(height: 50.00),
MaterialButton(
height: 50.00,
minWidth: 200.00,
child: const Text('Navigate to Next Screen'),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => BlocProvider<CounterCubit>.value(
value: BlocProvider.of<CounterCubit>(context),
child: const ThirdScreen(
title: 'Third Screen', color: Colors.amberAccent),
),
),
);
},
),
],
),
),
);
}
}
`Cubit state`
// ignore_for_file: unnecessary_this
part of 'counter_cubit.dart';
// #immutable
// abstract class CounterState {}
class CounterState {
int counterValue;
bool wasIncremented;
CounterState({
required this.counterValue,
required this.wasIncremented,
});
// #override
// List<Object> get props => [this.counterValue, this.wasIncremented];
}
`Cubit`
import 'package:bloc/bloc.dart';
part 'counter_state.dart';
class CounterCubit extends Cubit<CounterState> {
CounterCubit() : super(CounterState(counterValue: 0, wasIncremented: false));
void increment() => emit(
CounterState(counterValue: state.counterValue + 1, wasIncremented: true));
void decrement() => emit(CounterState(
counterValue: state.counterValue - 1, wasIncremented: false));
}
`Bloc is provided here`
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return BlocProvider<CounterCubit>(
create: (BuildContext context) => CounterCubit(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomeScreen(title: 'First Screen', color: Colors.blueAccent),
),
);
}
}
I have a ListView with ListTiles which set the tileColor property. All of the text and icons in the ListTile is clipped while the tileColor is visible beyond the ListView. How can I clip the entire ListTile so that nothing is visible beyond the ListView? I have tried wrapping ListView in various containers and the ListTile in a Container with no luck.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: const MyHomePage(title: 'Reminders'),
);
}
}
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> {
List _reminders = <String>[];
void _addReminder(String text) {
setState(() {
_reminders.add(text);
});
}
Widget _buildRow(String text, int i) {
return ListTile(
title: Text('[enter image description here][1]Reminder'),
trailing: IconButton(
onPressed: () {
setState(() {
_reminders.removeAt(i);
});
},
icon: Icon(Icons.delete)),
subtitle: Text(text),
tileColor: Colors.lightBlue,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
);
}
void _showMenu() {}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [IconButton(onPressed: _showMenu, icon: const Icon(Icons.list))],
),
body: Column(
children: <Widget>[
Container(
height: 400,
child: ListView.builder(
padding: EdgeInsets.all(8),
itemBuilder: (context, i) => _buildRow(_reminders[i], i),
itemCount: _reminders.length,
),
),
Container(
height: 100,
width: double.infinity,
child: Text('hello'),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_addReminder('hello there');
},
child: const Icon(Icons.add),
),
);
}
}
To solve your problem, wrap the Tile in a Material. Here is a tested solution. The explanation is below the code.
The short version:
Widget _buildRow(String text, int i) {
return Material(
child: ListTile(
title: Text('[enter image description here][$i]Reminder'),
trailing: IconButton(
onPressed: () {
setState(() {
_reminders.removeAt(i);
});
},
icon: const Icon(Icons.delete)),
subtitle: Text(text),
tileColor: Colors.lightBlue,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
));
}
The complete, working example:
```
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 MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: const MyHomePage(title: 'Reminders'),
);
}
}
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> {
final List _reminders = <String>[];
void _addReminder(String text) {
setState(() {
_reminders.add(text);
});
}
Widget _buildRow(String text, int i) {
return Material(child: ListTile(
title: Text('[enter image description here][$i]Reminder'),
trailing: IconButton(
onPressed: () {
setState(() {
_reminders.removeAt(i);
});
},
icon: const Icon(Icons.delete)),
subtitle: Text(text),
tileColor: Colors.lightBlue,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
));
}
void _showMenu() {}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [IconButton(onPressed: _showMenu, icon: const Icon(Icons.list))],
),
body: Column(
children: <Widget>[
Container(
height: 400,
child: ClipRect(
child: ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.all(8),
itemBuilder: (context, i) => _buildRow(_reminders[i], i),
itemCount: _reminders.length,
),
)
),
Container(
color: Colors.white,
width: double.infinity,
child: Text('hello'),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_addReminder('hello there');
},
child: const Icon(Icons.add),
),
);
}
}
```
This might be considered a bug, but it is expected behavior. The tile colors are painted by the first Material widget ancestor of the ListTile (I believe this allows it to optimize out expensive clipping). See the ListTile documentation for more information.
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
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 MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: const MyHomePage(title: 'Reminders'),
);
}
}
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> {
// ignore: prefer_final_fields
List _reminders = <String>[];
void _addReminder(String text) {
setState(() {
_reminders.add(text);
});
}
Widget _buildRow(String text, int i) {
return ListTile(
title: const Text('Reminder'),
trailing: IconButton(
onPressed: () {
setState(() {
_reminders.removeAt(i);
});
},
icon: const Icon(Icons.delete)),
subtitle: Text(text),
tileColor: Colors.lightBlue,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
);
}
void _showMenu() {}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [IconButton(onPressed: _showMenu, icon: const Icon(Icons.list))],
),
body: ListView.separated(
padding: const EdgeInsets.all(8),
itemBuilder: (context, i) => _buildRow(_reminders[i], i),
itemCount: _reminders.length, separatorBuilder: (BuildContext context, int index) {
return const SizedBox(height:10);},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_addReminder('hello there');
},
child: const Icon(Icons.add),
),
);
}
}
Here is my code with solution
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: const MyHomePage(title: 'Reminders'),
);
}
}
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> {
List _reminders = <String>[];
void _addReminder(String text) {
setState(() {
_reminders.add(text);
});
}
Widget _buildRow(String text, int i) {
return Container(
margin: EdgeInsets.symmetric(vertical: 5),
child: ListTile(
title: Text('[enter image description here][1]Reminder'),
trailing: IconButton(
onPressed: () {
setState(() {
_reminders.removeAt(i);
});
},
icon: Icon(Icons.delete)),
subtitle: Text(text),
tileColor: Colors.lightBlue,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
);
}
void _showMenu() {}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [
IconButton(onPressed: _showMenu, icon: const Icon(Icons.list))
],
),
body: Column(
children: <Widget>[
SizedBox(
height: 200,
child: ListView.builder(
scrollDirection: Axis.vertical,
padding: EdgeInsets.all(8),
itemBuilder: (context, i) => _buildRow(_reminders[i], i),
itemCount: _reminders.length,
),
),
Expanded(
child: Container(
color: Colors.white,
width: double.infinity,
child: Text('hello'),
),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_addReminder('hello there');
},
child: const Icon(Icons.add),
),
);
}
}
here is ss
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
I have a multiselect chip in my app , but when since the data in the AlertDialog depends dynamically, it will be 1 or 100, so I have added SingleChildScrollView over the alert Dialog to give scrolling if there are more entries , but when I added SingleChildScrollView my alert box goes to top of the screen like this, I want it to align in center,
If I removed the SingleChildScrollView then It will come like this which I wanted. but If there are lot of entries I cant select because It cant cover the entire data?
Is there any way where I can align it to center of screen with scroll enabled?
Thanks
showDialog(
context: context,
builder: (BuildContext context) {
return SingleChildScrollView(
child: AlertDialog(
title: Text("choose items"),
content: MultiSelectChip(
reportList,
onSelectionChanged: (selectedList) {
setState(() {
listSelectedItem = selectedList;
});
},
),
actions: <Widget>[
FlatButton(
child: Text("CANCEL"),
onPressed: () {
setState(() {
dropdownSelected = null;
listSelectedItem.clear();
});
Navigator.of(context).pop();
}),
In AlertDialog's content use Container and constraints, and in Container's child wrap SingleChildScrollView then wrap MultiSelectChip
code snippet
return AlertDialog(
title: Text("Report Video"),
content: Container(
constraints: BoxConstraints(
maxHeight: 100.0,
),
child: SingleChildScrollView(
child: MultiSelectChip(
reportList,
onSelectionChanged: (selectedList) {
setState(() {
selectedReportList = selectedList;
});
},
),
),
),
actions: <Widget>[
FlatButton(
child: Text("Report"),
onPressed: () => Navigator.of(context).pop(),
)
],
);
})
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> {
List<String> reportList = [
"Not relevant",
"Illegal",
"Spam",
"Offensive",
"Uncivil",
"a123",
"b234",
"c2314",
"aaaa",
"a",
"1Not relevant",
"2Illegal",
"3Spam",
"4Offensive",
"5Uncivil",
"6a123",
"7b234",
"8c2314",
"9aaaa",
"0a",
"Not relevant",
"Illegal",
"Spam",
"Offensive",
"Uncivil",
"a123",
"b234",
"c2314",
"aaaa",
"a",
"1Not relevant",
"2Illegal",
"3Spam",
"4Offensive",
"5Uncivil",
"6a123",
"7b234",
"8c2314",
"9aaaa",
"0a",
];
List<String> selectedReportList = List();
_showReportDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
//Here we will build the content of the dialog
return AlertDialog(
title: Text("Report Video"),
content: Container(
constraints: BoxConstraints(
maxHeight: 100.0,
),
child: SingleChildScrollView(
child: MultiSelectChip(
reportList,
onSelectionChanged: (selectedList) {
setState(() {
selectedReportList = selectedList;
});
},
),
),
),
actions: <Widget>[
FlatButton(
child: Text("Report"),
onPressed: () => Navigator.of(context).pop(),
)
],
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text("Report"),
onPressed: () => _showReportDialog(),
),
Text(selectedReportList.join(" , ")),
],
),
),
);
}
}
class MultiSelectChip extends StatefulWidget {
final List<String> reportList;
final Function(List<String>) onSelectionChanged;
MultiSelectChip(this.reportList, {this.onSelectionChanged});
#override
_MultiSelectChipState createState() => _MultiSelectChipState();
}
class _MultiSelectChipState extends State<MultiSelectChip> {
// String selectedChoice = "";
List<String> selectedChoices = List();
_buildChoiceList() {
List<Widget> choices = List();
widget.reportList.forEach((item) {
choices.add(Container(
padding: const EdgeInsets.all(2.0),
child: ChoiceChip(
label: Text(item),
selected: selectedChoices.contains(item),
onSelected: (selected) {
setState(() {
selectedChoices.contains(item)
? selectedChoices.remove(item)
: selectedChoices.add(item);
widget.onSelectionChanged(selectedChoices);
});
},
),
));
});
return choices;
}
#override
Widget build(BuildContext context) {
return Wrap(
children: _buildChoiceList(),
);
}
}