Animation in Flutter: How to resize a Stack? - flutter

What's the right way to animate a change in size of a Stack widget?
The first idea was to wrap the Stack with a SizeTransition:
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizeTransition(
sizeFactor: _height, // Just a Tween<double>(begin: 200, end: 400)
axis: Axis.vertical,
axisAlignment: -1,
child: Stack(
children: [
Positioned(
bottom: 10,
left: 10,
child: Container(width: 50, height: 50, color: Colors.blue),
),
Positioned(
top: 10,
right: 10,
child: Container(width: 50, height: 50, color: Colors.green),
),
],
),
),
],
);
}
But running the snippet causes the following error:
'package:flutter/src/rendering/stack.dart': Failed assertion: line 588 pos 12: 'size.isFinite': is not true.
So, apparently, that's not the right way to do it. Questions now is: How do you animate resizing of a Stack?
Wrapping the Stack with a SizedBox would fix the error message, but then, how do you get the size from SizedTransition to set the proper size of a SizedBox?

You can use AnimatedContainer as parent of Stack widget by providing height or width one you like to change over time.
AnimatedContainer(
color: Colors.purple,
duration: const Duration(milliseconds: 200),
height: height,
child: Stack(
children: [
Positioned(
bottom: 10,
left: 10,
child: Container(width: 50, height: 50, color: Colors.blue),
),
Positioned(
top: 10,
right: 10,
child: Container(width: 50, height: 50, color: Colors.green),
),
],
),
),

Related

two widgets on top of each other

I want to put another widget on the top corner of a container, and I want to put it slightly out of the container as in the picture below.
Use Stack widget and set its clipBehavior to none:
Stack(
clipBehavior: Clip.none, // <--- important part
children: [
Container(
width: 200,
height: 100,
color: Colors.blue,
),
Positioned(
right: -10,
top: -10,
child: Container(
width: 50,
height: 20,
color: Colors.green,
),
),
],
),

GirdView do not scroll to the page scroll effect of the SingleChildScrollView?

SingleChildScrollView(
child: Column(
children: [
Container(
height: 200.0,
width: double.infinity,
color: myBlue.withOpacity(.6),
child: TopCarouselSlider(bgColor: null),
),
//
Container(
height: MediaQuery.of(context).size.width * 1,
width: MediaQuery.of(context).size.width * 0.90,
color: myBlue.withOpacity(.5),
//
child: GridView.count(
mainAxisSpacing: 8,
crossAxisSpacing: 8,
crossAxisCount: 2,
children: [
Container(
height: 200.0,
width: 150.0,
color: myAccent,
),
Container(
height: 150.0,
width: 150.0,
color: myAccent,
),
Container(
height: 150.0,
width: 150.0,
color: myAccent,
),
Container(
height: 150.0,
width: 150.0,
color: myAccent,
)
],
),
),
],
),
),
Issue: If I try to scroll the page with the slide gesture inside the GridView area I don't get the scroll effect. Is this means that inside SingleChildScrollView the usual effects scroll for Grid or List will not work?
Please note I tried with GridView.Builder too, but the same result. Cannot figure a solution!
Thanks in advance for your help
you can do that using NestedScrollView or CustomScrollView, and it will work with sliverGrid and SliverList, but the problem is you can't add normal RenderBox widget like Container be the parent of the Slivers,

Flutter Container on top of rows

I made a bunch of rows. Now I want a Container on top of these rows. How can I do this. I tried it with the stack widget ,but it just stacked everything on top of each other and I had no control over the positioning.
How can I draw a Container on top of a bunch of rows.
Thank you for your help.
You can check the below code, though your asking is little bit confusing. You need to use Positioned and set some value at top and left.
Scaffold(
body: Stack(
children: [
Positioned(
top:0 ,
left: 0,
child: Container(
height: 100,
width: 100,
color: Colors.red,
),
),
Positioned(
top:100 ,
left: 0,
child: Container(
height: 100,
width: 100,
color: Colors.red,
child: Row(),
),
),
Positioned(
top:200 ,
left: 0,
child: Container(
height: 100,
width: 100,
color: Colors.red,
child: Row(),
),
),
Positioned(
top:300 ,
left: 0,
child: Container(
height: 100,
width: 100,
color: Colors.red,
child: Row(),
),
),
],
),
)

Image width, height not adjusting to the params in flutter

I am trying to scale down the image a bit so that it won't be cropped in grid item element. Actual image size is 300x300.
below is my code where I am explicitly trying to reduce the image width and height, I have also attempted many combinations with the fit type. I do not see any visible impact though. Can you let me know how should I achieve this? Thank you for your patience.
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
childAspectRatio: 1.5,
crossAxisCount: 2,
children: List.generate(
8,
(index) {
return Center(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(5),
child: CircleAvatar(
backgroundImage: Image.asset(
'assets/icons/antenna_icon.png',
height: 30,
width: 30,
fit: BoxFit.fitWidth,
).image,
backgroundColor: Colors.grey.shade300,
radius: 50,
)),
Text(
"Evve",
style: GoogleFonts.roboto(color: Colors.black87, fontSize: 15),
),
],
));
},
),
));
}
You can use Transform.scale as the child of the CircleAvatar and set the image as the child of the Transform.scale:
CircleAvatar(
child: Transform.scale(
scale: 0.8,
child: Image.asset(
'assets/icons/antenna_icon.png',
height: 30,
width: 30,
fit: BoxFit.fitWidth,
),
),
backgroundColor: Colors.grey.shade300,
radius: 50,
)

Flutter UI breaks when "smallest width" is changed in developer options

I am new into flutter programming. I have been working on a certain UI as shown below.
If I attempt to change the "smallest width" option in the developer options and set to some other value than the default, the whole UI breaks as shown.
I must add that the middle area which got completely broken was a stack widget.
#override
Widget build(BuildContext context) {
return Consumer<SinglePlayerGameState>(
builder: (context, gameState, child) => Expanded(
flex: 48,
child: Container(
color: gameState.getGameColor(),
child: Center(
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
child: Transform.rotate(
angle: 45,
child: UNOcard(UNOcardData(CardTypes.BACK)),
),
top: -30,
left: 90,
),
Positioned(
child: Transform.rotate(
angle: 65,
child: UNOcard(UNOcardData(CardTypes.BACK)),
),
top: 20,
left: 50,
),
Positioned(
child: Transform.rotate(
angle: 180,
child: UNOcard(UNOcardData(CardTypes.BACK)),
),
top: 100,
left: 65,
),
Positioned(
child: Transform.rotate(
angle: 45,
child: UNOcard(UNOcardData(CardTypes.BACK)),
),
top: 10,
right: 10,
),
Positioned(
child: Transform.rotate(
angle: 65,
child: UNOcard(UNOcardData(CardTypes.BACK)),
),
top: 120,
right: 50,
),
Positioned(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.black),
child: Text(
"${gameState.playingCards.length}",
style: TextStyle(
fontSize: 20,
fontFamily: 'Frijole',
color: Colors.white),
),
padding: EdgeInsets.all(7),
),
top: 10,
left: 10,
),
Positioned(
child: SizedBox(
child: Center(
child: FlatButton(
onPressed: () {
gameState.nextTurn();
},
child: Icon(
FontAwesomeIcons.undoAlt,
size: 25,
),
color: Colors.white,
)),
height: 35,
width: 60,
),
bottom: 10,
left: 10,
),
Positioned(
child: DragTarget<UNOcardData>(
onWillAccept: (UNOcardData data) {
var res = isValidMove(
data, gameState.onGoingCards.last, gameState);
if(res){
print(res);
return true;
}else{
vibrate();
return false;
}
},
onAccept: (UNOcardData data) {
print(data);
performAction(data, gameState);
},
builder: (context, candidateData, rejectedData) =>
Transform.rotate(
angle: 0,
child: gameState.onGoingCards.last,
),
),
top: 60,
right: 100,
),
],
),
),
),
),
);
}
}
Like we use units like "vmin , vmax , vh " etc in html/css for responsive texts and sizes, what are the alternatives in flutter ? How do we responsive apps in flutter exactly ? I am not talking about scaling to other screen sizes, but to slightly different resolutions and logical pixel densities.
Thanks for your time.
That's because you are using margins from the edges with
Positioned(
child: Transform.rotate(
angle: 180,
child: UNOcard(UNOcardData(CardTypes.BACK)),
),
top: 100,
left: 65,
),
This top means that it's going to position itself 100 units from the top. What you actually want is some percentage offset from the center. You can do it like this:
Positioned.fill(
child: Align(
// (0, 0) is the center, (1, 1) is right bottom, (-1, -1) is left top and so on
alignment: Alignment(0.25, 0.25),
child: YOUR_WIDGET
)
);
For more responsive UI you can get screen_sizes with MediaQuery.of(context) or use a package like flutter_screenutil to scale your UI according to a sample, like for example 1080x1920 screen.