How do I end up with smooth DragEnd Flutter - android

How do I end the drop with proper velocity to a given offset
I am trying make something similar to SlidingUpPanel, but can't figure out how to implement.
final bottom = ValueNotifier<double>(0.0);
Stack(
children: [
ValueListenableBuilder<double>(
valueListenable: bottom,
builder: (context, value, child) => Positioned(
bottom: value,
left: 0,
right: 0,
child: GestureDetector(
onVerticalDragStart: (value) {
},
onVerticalDragUpdate: (DragUpdateDetails value) {
bottom.value -= value.delta.dy;
},
onVerticalDragEnd: (value) {
const double minFlingVelocity = 365.0;
if (value.velocity.pixelsPerSecond.dy.abs() >=
minFlingVelocity) {
// bottom.value =
// MediaQuery.of(context).size.height / 2;
}
},
child: Container(
width: double.maxFinite,
height: 200,
color: Colors.green,
),
),
),
)
],
),

Related

How to center a widget inside a stack and moving it programmatically?

I have a widget in a stack that should be centered in the stack initially. The user should be able to move the widget programmatically in the stack.
I have tried a number of things. I can center the widget by setting the alignment of Stack to center using alignment: Alignment.center of the stack. And if the no TRBL properties of the Positioned widget is not set, then the widget is centered. But Then how do you move the widget from center to 2 pixels above center or 5 pixel right?
Stack(
alignment: Alignment.center,
children: [
Positioned(
child:Container(
height: 50,
width: 50,
child: Text('Move this programmatically')
)
)
]
)
You can play with this widget. I am using LayoutBuilder.
class StackAMovement extends StatefulWidget {
const StackAMovement({super.key});
#override
State<StackAMovement> createState() => _StackAMovementState();
}
class _StackAMovementState extends State<StackAMovement> {
double shiftX = 0;
double shiftY = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
shiftY += 2;
shiftX += 5;
setState(() {});
},
),
body: LayoutBuilder(
builder: (p0, constraints) {
final centerW = constraints.maxWidth / 2;
final centerH = constraints.maxHeight / 2;
return Stack(
children: [
Positioned(
left: centerW + shiftX -25,//-25 half of container width
top: centerH + shiftY -25,//-25 half of container height
child: Container(
color: Colors.purple,
height: 50,
width: 50,
child: Text('Move this programmatically')))
],
);
},
),
);
}
}
Stack(
alignment: Alignment.center,
children: [
Positioned.fill(
child:Center(
child:Container(
height: 50,
width: 50,
child: Text('Move this programmatically')
))
)
]
)
you can use this. very easy:
Stack(
alignment: Alignment.center,
children: [
Positioned(
left:1,
right:1,
child:Container(
height: 50,
width: 50,
child: Text('Move this programmatically')
)
)
]
)

Flutter concatenate bool variable with loop index

I have data in getData() from API and there is a list of data shown in UI and every item in the list is clickable. so want to add a bool type variable in for loop with the value i but I don't know how to concatenate the variable name with i. and the working of this bool variable in _navigateSlide(BuildContext context) widget. so when i add a bool variable in for loop with index i in getData() like
for (int i = 0; i < value.length; i++) { bool check[i] = false; }
it shows me an error of
Illegal assignment to non-assignable expression. Missing selector such as '.identifier' or '[0]'. on code check[i]
Here is my code:-
class ExploreAds extends StatefulWidget {
ExploreAds({Key? key}) : super(key: key);
#override
_ExploreAds createState() => _ExploreAds();
}
class _ExploreAds extends State<ExploreAds> {
bool show = false;
bool checkother = false;
final List<String> data = <String>[];
void addValue(txt) {
setState(() {
data.add('${txt}');
});
print(data);
}
void removeValue(rmtxt) {
setState(() {
data.remove('${rmtxt}');
});
print(data);
}
var catdata;
#override
void initState() {
super.initState();
getData();
}
getData() async{
await BuySellCatsController().buysellCatAPI().then((value) {
for (int i = 0; i < value.length; i++) {
bool check[i] = false;
}
}
);
}
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
final ThemeData themeData = Theme.of(context);
const double padding = 25;
const sidePadding = EdgeInsets.symmetric(horizontal: padding);
return Scaffold(
body: Container(
height: 550,
child: catdata != null?
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
addVerticalSpace(10),
Expanded(
child : Container(
child: GridView(
padding: EdgeInsets.only(right:8,),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
childAspectRatio: 0.70,
),
children: List.generate(catdata.length + 1,
(index) => index == catdata.length ?
Stack(
children: [
Container(
padding: EdgeInsets.only(right:5, left:5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Color(0xffacacac)),
),
child: InkWell(
onTap: () => setState(
() {
checkother = !checkother ;
checkother ? addValue('Others') : removeValue('Others');
},
),
child: Column(
children: [
Image.asset('assets/icons/pngwing49.png', width: 115, height: 115),
Text('Others')
],
)
),
),
Visibility(
visible: check6 ? true : false,
child: Positioned(
top: 5,
right: 5,
child: Image.asset('assets/icons/tick.png', width: 15,),
)
)
],
):
Stack(
children: [
Container(
padding: EdgeInsets.only(right:5, left:5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Color(0xffacacac)),
),
child: InkWell(
onTap: () => setState(
() {
check[index] = !check[index];
check[index]? addValue('${catdata[index]['name']}') : removeValue('${catdata[index]['name']}');
},
),
child: Column(
children: [
Image.network('${catdata[index]['image']}', width: 115, height: 115,),
Text('${catdata[index]['name']}')
],
)
),
),
Visibility(
visible: check[index] ? true : false,
child: Positioned(
top: 5,
right: 5,
child: Image.asset('assets/icons/tick.png', width: 15,),
)
)
],
)
),
),
),
),
addVerticalSpace(10),
Padding(
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: ElevatedButton(
onPressed: () => Navigator.pop(context, 'Cancel'),
style: ElevatedButton.styleFrom(
elevation: 6,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(80.0)),
padding: const EdgeInsets.all(0.0),
),
child: Ink(
decoration: const BoxDecoration(
gradient: LinearGradient(colors: [Color(0xfff9568f), Color(0xfffabaae)],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Container(
constraints: const BoxConstraints(minWidth: 88.0, minHeight: 50.0), // min sizes for Material buttons
alignment: Alignment.center,
child: const Text(
'Apply',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
),
)
],
):
const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.white,
strokeWidth: 2,
color: Color(0xffe93332),
)
),
)
);
}
}
please help how can I do this? if anyone knows please help me.
You are declaring and assigning a variable inside the loop.
From your code, I'm assuming you want to get a list of bool values, that should have the length equal to value.length - all set to fale.
Note - no need to use .then when you are already using await.
You shoud have something like this:
Future<List<bool>> getData() async{
var value = await BuySellCatsController().buysellCatAPI();
return List.filled(value.length, false);
}
If you really wanted to use .then and for loop, here's how it would work
Future<List<bool>> getData() async{
return await BuySellCatsController().buysellCatAPI().then((value) {
var check=<bool>[];
for (int i = 0; i < value.length; i++) {
check.add(false);
}
}
);
}

flutter can not drawImage at exact offset with canvas.drawImage

Hello i am creating flutter app and trying to draw image and i successfully did that from below answer
This is the main answer from where i can get idea about dropping pin on tap
From this answer i am drwaing image successfully
but issue is that pin is not drawn to exact offset(x&y) position here i am attaching screen shot so you can get better idea.
Here is the screen shot please take a look at the exact issue
and here is my code from which i can get x and y position where user tapped
return Scaffold(
appBar: AppBar(
title: Text(widget.title,style: TextStyle(color: Colors.white),),
backgroundColor: Color.fromRGBO(86, 35, 127, 1),
brightness: Brightness.dark
),
body: SafeArea(
top: true,
bottom: true,
left: true,
right: true,
child: Stack(
children: [
Listener(
onPointerDown: (PointerDownEvent event) {
RenderBox referenceBox = _paintKey.currentContext.findRenderObject();
Offset offset = referenceBox.globalToLocal(event.position); // here i am getting offset where user tapped
setState(() {
_offset = offset;
isDroppedPin = true;
});
if (widget.pinNo <= 5){
}else{
Toast.show("Maximum Pin Limit Reached", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
}
},
child: InteractiveViewer(
minScale: 0.1,
maxScale: 3,
child: Stack(
children: [
new CustomPaint(
key: _paintKey,
painter: new MyCustomPainter(_image,_offset),
),
],
),
),
),
Positioned.fill(
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color.fromRGBO(86, 35, 127, 1), // background
onPrimary: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5)),
),// foreground
),
onPressed: () {
if (isDroppedPin == false){
Toast.show("Please Add pin", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
}else{
Navigator.push(context, EOBAElementFormRoute(_offset.dx.toString(),_offset.dy.toString(),widget.title,widget.pinNo,widget.image_url,widget.type,widget.drawing_id));
}
},
child: Container(
width: double.infinity,
child: Text('Next', style: TextStyle(color: Colors.white,fontSize: 17,fontWeight: FontWeight.w500),textAlign: TextAlign.center,),
),
),
),
),
)
],
),
)
);
and here is class where pin is drawing
class MyCustomPainter extends CustomPainter {
ui.Image image;
final Offset _offset;
MyCustomPainter(this.image,this._offset) : super();
#override
Future paint(Canvas canvas, Size size) async {
if (image != null) {
canvas.drawImage(image, _offset, new Paint());
}
}
#override
bool shouldRepaint(MyCustomPainter other) => other._offset != _offset;
}
can any one have idea why pin is not drawn to exact position where user tapped

How to specify drag target for a certain widget Flutter (Single Draggable Being Dropped Into 3 Drag Targets Instead Of 1)

Here is the problem that I am facing:
I start off with a list of emoji's which I want to drop into these 3 Drop Targets
(I want to be able to select each emoji which goes into each of these drop targets)
When I drag one of these emojis (only one, which is in this case, the first one, it automatically drops into all the drag targets instead of only the first one).
This results in the same emoji populating all the drag targets unintentionally like this which is unexpected behavior:
My question is, how can I change my code so that I can make sure that, when I drag on emoji into the first, second, or third Drag target, only that respective drag target gets filled instead of all of them? Thanks a lot and I really appreciate your help!
Code For DragBox:
class DragBox extends StatefulWidget {
DragBox({this.animatedAsset, this.width});
final LottieBuilder animatedAsset;
final double width;
#override
_DragBoxState createState() => _DragBoxState();
}
class _DragBoxState extends State<DragBox> {
#override
Widget build(BuildContext context) {
return Draggable(
feedback: Container(
width: 50,
height: 50,
child: widget.animatedAsset,
),
child: Container(
child: widget.animatedAsset,
width: widget.width,
height: 50,
),
childWhenDragging: Container(),
data: widget.animatedAsset,
);
}
}
Code For Emoji Picker :
class AnimatedEmojiPicker extends StatefulWidget {
#override
_AnimatedEmojiPickerState createState() => _AnimatedEmojiPickerState();
}
class _AnimatedEmojiPickerState extends State<AnimatedEmojiPicker> {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: 60,
decoration:
BoxDecoration(color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 15,
),
DragBox(
animatedAsset: Lottie.asset('Assets/blushing.json'),
),
Container(
width: 15,
),
DragBox(
animatedAsset: Lottie.asset('Assets/cooldude.json'),
),
Container(
width: 15,
),
DragBox(
animatedAsset: Lottie.asset('Assets/zipmouth.json'),
),
//More drag boxes like this one
],
),
),
);
}
}
My Drag targets:
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
widget.caughtAnimation = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: widget.caughtAnimation,
),
);
},
),
Padding(
padding: const EdgeInsets.all(8.0),
child: DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
widget.caughtAnimation = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5),
borderRadius: BorderRadius.circular(20.0)),
child: widget.caughtAnimation,
),
);
},
),
),
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
widget.caughtAnimation = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: widget.caughtAnimation,
),
);
},
),
],
),
Again, thanks for any help!
This is happening because on each DragTarget you are building the same widget.caughtAnimation that you set on any onAccept callback.
Consider structuring your widget state model in a way that you can individually modify each DragTarget, this can be done with a List/array or a map.
List<LottieBuilder> caughtAnimations;
then
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
caughtAnimations[0] = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: caughtAnimations[0],
),
);
},
),
Padding(
padding: const EdgeInsets.all(8.0),
child: DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
caughtAnimations[1] = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5),
borderRadius: BorderRadius.circular(20.0)),
child: caughtAnimations[1],
),
);
},
),
),
DragTarget(
onAccept: (LottieBuilder animation) {
setState(() {
caughtAnimations[2] = animation;
});
},
builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
return Center(
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
child: caughtAnimations[2],
),
);
},
),
],
),

Animation with hero and showDialog in flutter

i need help for recreate this sample animation with flutter, i try with using showDialog() but i don't see animation, i used Hero() with tag but don'work, please help me!
it can be done using Stack, AnimatedPositioned and AnimatedContainer:
check sample code below:
import 'package:flutter/material.dart';
class MyPage extends StatefulWidget {
#override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
bool isOpen = false;
// AnimatedContainer dimensions:
double width = 55, height = 55;
// AnimatedPositioned positions:
double left = 20, bottom = 20;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
color: Color(0xff151515),
child: Stack(
children: <Widget>[
Positioned(
left: 0,
top: 0,
right: 0,
bottom: 0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("TIMER", style: TextStyle(color: Colors.white, fontSize: 36, fontWeight: FontWeight.w700),),
Text("00 : 00", style: TextStyle(color: Colors.white, fontSize: 36, fontWeight: FontWeight.w700),),
],
),
),
Positioned(
left: 0,
top: 0,
right: 0,
bottom: 0,
child: GestureDetector(
child: AnimatedOpacity(
// If the widget is visible, animate to 0.0 (invisible).
// If the widget is hidden, animate to 1.0 (fully visible).
opacity: isOpen ? 1.0 : 0.0,
duration: Duration(milliseconds: 500),
// The green box must be a child of the AnimatedOpacity widget.
child: Container(
width: 200.0,
height: 200.0,
color: Colors.black45,
),
),
onTap: () {
if (isOpen) {
setState(() {
width = 55; height = 55;
left = 20; bottom = 20;
isOpen = false;
});
}
},
),
),
AnimatedPositioned(
left: left,
bottom: bottom,
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut,
child: GestureDetector(
child: AnimatedContainer(
width: width,
height: height,
decoration: new BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(28)),
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut,
// child: dialog container content goes here,
),
onTap: () {
if (!isOpen) {
setState(() {
width = 200; height = 200;
left = 60; bottom = 60;
isOpen = !isOpen;
});
}
},
),
),
Positioned(
bottom: 30,
left: 40,
child: IgnorePointer(
child: Text(
'1',
style: TextStyle(color: Colors.white, fontSize: 30),
),
),
),
],
),
),
),
);
}
}

Categories

Resources