How to animate AnimatedContainer to fill all available space - animation

Basically i want to animate an AnimatedContainer's height between 2 values. But here is the problem. When my state is 1 i know the height so i can animate but when my state is 0 i want animated container to expand to available space. I tried to wrap my animated container with Expanded widget but that didn't work.
class _PreviewScreenState extends State<PreviewScreen> {
var selectedTab = 1;
#override
Widget build(BuildContext context) {
double imageWidth = MediaQuery.of(context).size.width;
double imageHeight = selectedTab == 1 ? imageWidth : null;
return Scaffold(
body: DefaultTabController(
length: 3,
initialIndex: selectedTab,
child: Background(
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: Text('SHARE'),
),
Expanded(
child: AnimatedContainer(
height: imageHeight,
duration: Duration(milliseconds: 600),
color: Colors.red,
),
),
TabBar(
labelStyle: TextStyle(fontSize: 13),
indicator: BoxDecoration(
color: Colors.white24,
borderRadius: BorderRadius.circular(40),
),
onTap: (index) {
setState(() {
selectedTab = index;
});
},
tabs: <Widget>[
Tab(child: Text('INSTAGRAM')),
Tab(child: Text('SQUARE')),
Tab(child: Text('OTHER'))
],
),
Container(
height: 100,
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: ShareButton(
onPressed: () {},
),
),
),
)
],
),
),
),
),
);
}
}

You can use a Flexible widget instead of an Expanded widget. It gives the child "the flexibility to expand to fill the available space in the main axis, but, unlike Expanded, Flexible does not require the child to fill the available space."
Also, you should switch from AnimatedContainer to AnimatedSize as AnimatedContainer throws an error interpolating between double.infinity and a constant height.
So this
Expanded(
child: AnimatedContainer(
height: imageHeight,
duration: Duration(milliseconds: 600),
color: Colors.red,
),
),
will be come
Flexible(
child: AnimatedSize(
vsync: this,
duration: Duration(milliseconds: 600),
child: Container(
height: imageHeight,
color: Colors.red,),
),
),
For this to work, your _PreviewScreenState has to use the SingleTickerProviderStateMixin mixin and your imageHeight logic will have to change from null to double.infinity for the filling the available space.
i.e you will have:
class _PreviewScreenState extends State<PreviewScreen> with SingleTickerProviderStateMixin{
//rest of your code
}
and
double imageHeight = selectedTab == 1 ? imageWidth : double.infinity;
Here is a DartPad demonstration: https://dartpad.dev/bf4f969f76ab3092d0b1960bfdbf7825

Related

How to display active textfields hidden by the front panel?

I have been trying to display backdrop with searching fiture. but when I tap the textfield is hidden by front panel. how to front panel not hidden the search textfield ?
import 'package:flutter/material.dart';
import 'content_isi.dart';
class Panel extends StatefulWidget {
final AnimationController controller;
Panel({this.controller});
#override
_PanelState createState() => new _PanelState();
}
class _PanelState extends State<Panel> {
static const header_height = 200.0;
Animation<RelativeRect> getPanelAnimation(BoxConstraints constraints) {
final height = constraints.biggest.height;
final backPanelHeight = height - header_height;
final frontPanelHeight = -header_height;
return new RelativeRectTween(
begin: new RelativeRect.fromLTRB(
0.0, backPanelHeight, 0.0, frontPanelHeight),
end: new RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0))
.animate(new CurvedAnimation(
parent: widget.controller, curve: Curves.linear));
}
Widget bothPanels(BuildContext context, BoxConstraints constraints) {
final ThemeData theme = Theme.of(context);
return new Container(
child: new Stack(
children: <Widget>[
new Container(
color: Colors.white,
child: Column(
children: <Widget>[
TextField(
decoration:
_buildInputDecoration(Icons.tune, 'Jenis Peraturan'),
),
Divider(
height: 0.0,
color: Colors.grey,
),
TextField(
decoration: _buildInputDecoration(Icons.pages, 'Nomor'),
),
Divider(
height: 0.0,
color: Colors.grey,
),
TextField(
decoration: _buildInputDecoration(Icons.pages, 'Tahun'),
),
Divider(
height: 0.0,
color: Colors.grey,
),
TextField(
decoration:
_buildInputDecoration(Icons.help_outline, 'Tentang'),
),
Container(
padding: EdgeInsets.only(left: 5.0, right: 5.0),
width: double.infinity,
child: FlatButton(
onPressed: () {},
child: Text(
'Cari',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16),
),
color: Colors.blue,
),
),
],
),
),
new PositionedTransition(
rect: getPanelAnimation(constraints),
child: new Material(
elevation: 12.0,
child: ListView(
children: <Widget>[
ContentIsi(
no: '11',
th: '2020',
jnsperaturan: 'Peraturan BBB',
judul:
'Perubahan Keempat Atas Peraturan Nomor 1 Tahun 2017 tentang Pelimpahan Kewenangan Penandatanganan Perizinan dan Non Perizinan Kepada Kepala Dinas Penanaman Modal dan Pelayanan Terpadu Satu Pintu',
onPressed: null,
)
],
),
),
)
],
),
);
}
#override
Widget build(BuildContext context) {
return new LayoutBuilder(
builder: bothPanels,
);
}
InputDecoration _buildInputDecoration(IconData icon, String hintText) {
return InputDecoration(
prefixIcon: Padding(
padding: const EdgeInsets.only(right: 32.0, left: 16.0),
child: Icon(icon),
),
hintText: hintText,
contentPadding: const EdgeInsets.symmetric(vertical: 16.0),
border: InputBorder.none,
);
}
}
I'm the beginner of flutter. so i hope you can help me about it.
the gif image in the below :
in the image gif the textfield hidden by front pannel (listview) when I tap the textfield. how to fix it ????

Slide transition is very slow

My senario is my image and buttons in the center of the screen but my image on the top of them so i'm using stack , then after 2 seconds my image move slightly to the top and my buttons to the bottom.
so i'm using slide transition to move an Image slightly to the top and other buttons to the bottom, and it works but it's very slow even on a real device after release.
is there any solution to fix it or a better approach ?
thanks in advance
my code
class StartView extends StatefulWidget {
#override
_StartViewState createState() => _StartViewState();
}
class _StartViewState extends State<StartView> with TickerProviderStateMixin {
bool showOptions = false;
AnimationController controller;
Animation<Offset> offset;
Animation<Offset> offset2;
Animation<Offset> offset3;
bool _isLoadingVisitor = false;
#override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 1));
offset = Tween<Offset>(begin: Offset.zero, end: Offset(0, -.5))
.animate(controller);
offset2 = Tween<Offset>(begin: Offset.zero, end: Offset(0, .8))
.animate(controller);
offset3 = Tween<Offset>(begin: Offset.zero, end: Offset(0, 2))
.animate(controller);
}
#override
void dispose() {
// TODO: implement dispose
super.dispose();
controller.dispose();
}
#override
Widget build(BuildContext context) {
ScreenUtil.init(context, width: 376, height: 670, allowFontScaling: false);
Future.microtask(()=>Future.delayed(Duration(seconds: 2), () {
controller.forward();
}));
return SafeArea(
child: Scaffold(
body: Container(
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: SlideTransition(
position: offset2,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)),
child: Text(
Localization.of(context).trans('login'),
style: TextStyle(
fontSize: ScreenUtil().setSp(20),
fontFamily: 'JFFlatregular'),
),
elevation: 0,
onPressed: login,
),
)),
Align(
alignment: Alignment.center,
child: SlideTransition(
position: offset3,
child: _isLoadingVisitor
? CircularProgressIndicator()
: FlatButton(
child: Text(
Localization.of(context).trans('login_as_visitor'),
style: TextStyle(
fontSize: ScreenUtil().setSp(20),
fontFamily: 'JFFlatregular'),
),
onPressed: loginVisitor,
),
),
),
Align(
alignment: Alignment.center,
child: SlideTransition(
position: offset,
child: Image.asset(
'assets/images/splash.png',
width: ScreenUtil().setWidth(250),
height: ScreenUtil().setHeight(250),
fit: BoxFit.fill,
filterQuality: FilterQuality.high,
),
),
),
],
),
),
),
);
}
}
Image resolution was too high 2040*2040 when i resized it , it works just fine

Images load by themselves, but not as a randomized list. - Flutter

and thank you in advance for any assistance.
So, I have images load properly when I use them within a container in other areas of the code, but I also want some of those images to display randomly within the AppBar.
Given that they do load in other locations within the code, I don't suspect a Pubyaml error.
I'm still fairly new to flutter, and lists in general. So I wouldn't be surprised if I messed up something with the list itself, or the way it's called.
It gives me this error:
Syncing files to device iPhone...
Reloaded 8 of 502 libraries in 411ms.
════════ Exception caught by image resource service ════════════════════════════════════════════════
The following assertion was thrown resolving an image codec:
Unable to load asset: Image(image: AssetImage(bundle: null, name: "images/Mem2.JPG"), frameBuilder: null, loadingBuilder: null, alignment: center, this.excludeFromSemantics: false, filterQuality: low)
When the exception was thrown, this was the stack:
#0 PlatformAssetBundle.load (package:flutter/src/services/asset_bundle.dart:221:7)
<asynchronous suspension>
#1 AssetBundleImageProvider._loadAsync (package:flutter/src/painting/image_provider.dart:484:44)
#2 AssetBundleImageProvider.load (package:flutter/src/painting/image_provider.dart:469:14)
#3 ImageProvider.resolve.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:327:17)
...
Image provider: AssetImage(bundle: null, name: "Image(image: AssetImage(bundle: null, name: "images/Mem2.JPG"), frameBuilder: null, loadingBuilder: null, alignment: center, this.excludeFromSemantics: false, filterQuality: low)")
Image key: AssetBundleImageKey(bundle: PlatformAssetBundle#c99db(), name: "Image(image: AssetImage(bundle: null, name: "images/Mem2.JPG"), frameBuilder: null, loadingBuilder: null, alignment: center, this.excludeFromSemantics: false, filterQuality: low)", scale: 1.0)
════════════════════════════════════════════════════════════════════════════════════════════════════
Here's the code:
class ContactProfilePage extends StatefulWidget {
#override
_ContactProfilePageState createState() => _ContactProfilePageState();
}
class _ContactProfilePageState extends State<ContactProfilePage> {
List<Attr> attr = [
Attr(name: ''),
];
dynamic randAppBarImg = [
"images/Mem2.JPG",
"images/Mem3.JPG",
"images/Mem4.JPG",
"images/Mem6.jpg",
"images/memory - 1.jpeg",
"images/memory - 2.jpeg",
"images/memory - 3.jpeg",
"images/memory - 4.jpeg",
"images/memory - 5.jpeg",
"images/memory - 6.jpeg",
];
Random rnd;
Image img() {
int min = 0;
int max = randAppBarImg.length - 1;
rnd = Random();
int r = min + rnd.nextInt(max - min);
String image_name = randAppBarImg[r].toString();
return Image.asset(image_name);
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.lightBlueAccent,
child: Icon(Icons.add),
onPressed: () {
//Modal sheet brings up the whole bottom pane when the plus button is pressed.
showModalBottomSheet(
context: context,
builder: (context) => AddAttrScreen(
(newAttrTitle) {
setState(() {
//adds the Attr to the list anytime the user presses "Add"
attr.add(Attr(name: newAttrTitle));
});
Navigator.pop(context);
//Hides the floating add Attr screen after pressing "Add"
},
),
);
//TODO Change it so the categories don't have to be selected every time. Instead, have the add button WITHIN each category.
// This floating button should instead create a new category.
},
),
drawer: DrawerMain(),
body: NestedScrollView(
//This allows for the top bar to collapse, while retaining the image.
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: true,
snap: true,
pinned: true,
flexibleSpace: Stack(
children: <Widget>[
Positioned.fill(
child: Image.asset(
img().toString(),
fit: BoxFit.cover,
))
],
),
),
];
},
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(15.0),
child: CircleAvatar(
maxRadius: 50.0,
backgroundImage: AssetImage("images/fox.jpeg")),
),
Container(
//TODO ADD ON PRESSED FUNCTION TO SOCIAL ICONS
margin: EdgeInsets.all(15.0),
child: Icon(
FontAwesomeIcons.facebook,
size: 40.0,
color: Color(0xFF306060),
),
),
Container(
margin: EdgeInsets.all(15.0),
child: Icon(
FontAwesomeIcons.instagram,
size: 40.0,
color: Color(0xFF306060),
),
),
],
),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Armando Pacheco Ortiz',
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
color: Color(0xFF306060)),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Freelance App Developer from Puerto Rico',
style: TextStyle(
fontSize: 20.0,
fontStyle: FontStyle.italic,
color: Color(0xFF306060)),
),
SizedBox(
child: Divider(),
),
],
),
),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
children: <Widget>[
Text('Memories',
style: TextStyle(
fontSize: 20.0,
fontStyle: FontStyle.italic,
color: Color(0xFF306060),
fontWeight: FontWeight.bold))
],
),
),
//Horizontal scrolling images.
//TODO These need to update based on uploads, perhaps use something like google's face detection to auto add?
Padding(
padding: const EdgeInsets.all(15.0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
height: 310,
width: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: (Image.asset(
'images/Mem6.jpg',
fit: BoxFit.cover,
)),
),
),
SizedBox(
width: 20,
),
Container(
height: 310,
width: 200,
//ClipRRect allows for it to have the border radius. Container is painted behind the image.
//For that reason, adding a border radius to the container doesn't work.
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: (Image.asset(
'images/Mem2.JPG',
fit: BoxFit.cover,
)),
),
),
SizedBox(
width: 20,
),
Container(
height: 310,
width: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: (Image.asset(
'images/memory - 4.jpeg',
fit: BoxFit.cover,
)),
),
),
I pasted the code as far down as the first image, to show how I have it set up in the other locations.
I'm not sure if the issue is with random images within the appBar, or maybe some code I'm missing.
Hopefully, someone can shed some light on this!
Many thanks.
UPDATE:
So that helped a ton and definitely got things running! But I did notice two new problems cropping up.
I had to rename all the images from: "memory - 6" to "Mem6", and that finally allowed them to show up.
Otherwise, sometimes it would revert back to the default teal color, and not display anything, besides an error about not being able to load the asset again. I imagine it's just a naming error I was unknowingly causing?
Scrolling down will cause the Appbar to "refresh" again, and randomize the pictures with the slightest scrolling until you stop. If I scroll back up, it'll do it again. It doesn't create an error, but it does crash the app eventually from so much refreshing I guess.
How would I get around this? Is there an override, or should I simply create the widget with some Finals, or stateless/stateful widgets? I'm still learning the lingo and all that, so my apologies for the ignorance.
You can copy paste run full code below
Your img() has bug, you return an Image.asset and wrap in Image.asset again cause duplicate
Image.asset(
img().toString(),
fit: BoxFit.cover,
))
code snippet just return String of image_name will work
and do not include space in image name
String img() {
int min = 0;
int max = randAppBarImg.length - 1;
rnd = Random();
int r = min + rnd.nextInt(max - min);
String image_name = randAppBarImg[r].toString();
//return Image.asset(image_name);
return image_name;
}
working demo
full code
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:font_awesome_flutter/font_awesome_flutter.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: ContactProfilePage(),
);
}
}
class Attr {
String name;
Attr({this.name});
}
class ContactProfilePage extends StatefulWidget {
#override
_ContactProfilePageState createState() => _ContactProfilePageState();
}
class _ContactProfilePageState extends State<ContactProfilePage> {
List<Attr> attr = [
Attr(name: ''),
];
dynamic randAppBarImg = [
"images/Mem2.JPG",
"images/Mem3.JPG",
/*"images/Mem4.JPG",
"images/Mem6.jpg",
"images/memory-1.jpeg",
"images/memory-2.jpeg",
"images/memory-3.jpeg",
"images/memory-4.jpeg",
"images/memory-5.jpeg",
"images/memory-6.jpeg",*/
];
Random rnd;
String img() {
int min = 0;
int max = randAppBarImg.length - 1;
rnd = Random();
int r = min + rnd.nextInt(max - min);
String image_name = randAppBarImg[r].toString();
//return Image.asset(image_name);
return image_name;
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.lightBlueAccent,
child: Icon(Icons.add),
onPressed: () {
//Modal sheet brings up the whole bottom pane when the plus button is pressed.
/* showModalBottomSheet(
context: context,
builder: (context) => AddAttrScreen(
(newAttrTitle) {
setState(() {
//adds the Attr to the list anytime the user presses "Add"
attr.add(Attr(name: newAttrTitle));
});
Navigator.pop(context);
//Hides the floating add Attr screen after pressing "Add"
},
),
);*/
//TODO Change it so the categories don't have to be selected every time. Instead, have the add button WITHIN each category.
// This floating button should instead create a new category.
},
),
//drawer: DrawerMain(),
body: NestedScrollView(
//This allows for the top bar to collapse, while retaining the image.
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: true,
snap: true,
pinned: true,
/*flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text("",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
)),
background: Image.asset(
"images/Mem2.JPG",
fit: BoxFit.cover,
)),*/
flexibleSpace: Stack(
children: <Widget>[
Positioned.fill(
child: Image.asset(
img().toString(),
fit: BoxFit.cover,
))
],
),
),
];
},
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(15.0),
child: CircleAvatar(
maxRadius: 50.0,
backgroundImage: AssetImage("images/fox.jpeg")),
),
Container(
//TODO ADD ON PRESSED FUNCTION TO SOCIAL ICONS
margin: EdgeInsets.all(15.0),
child: Icon(
FontAwesomeIcons.facebook,
size: 40.0,
color: Color(0xFF306060),
),
),
Container(
margin: EdgeInsets.all(15.0),
child: Icon(
FontAwesomeIcons.instagram,
size: 40.0,
color: Color(0xFF306060),
),
),
],
),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Armando Pacheco Ortiz',
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
color: Color(0xFF306060)),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Freelance App Developer from Puerto Rico',
style: TextStyle(
fontSize: 20.0,
fontStyle: FontStyle.italic,
color: Color(0xFF306060)),
),
SizedBox(
child: Divider(),
),
],
),
),
Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
children: <Widget>[
Text('Memories',
style: TextStyle(
fontSize: 20.0,
fontStyle: FontStyle.italic,
color: Color(0xFF306060),
fontWeight: FontWeight.bold))
],
),
),
//Horizontal scrolling images.
//TODO These need to update based on uploads, perhaps use something like google's face detection to auto add?
Padding(
padding: const EdgeInsets.all(15.0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
height: 310,
width: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: (Image.asset(
'images/Mem6.jpg',
fit: BoxFit.cover,
)),
),
),
SizedBox(
width: 20,
),
Container(
height: 310,
width: 200,
//ClipRRect allows for it to have the border radius. Container is painted behind the image.
//For that reason, adding a border radius to the container doesn't work.
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset(
'images/Mem2.JPG',
fit: BoxFit.cover,
),
),
),
SizedBox(
width: 20,
),
Container(
height: 310,
width: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: (Image.asset(
'images/memory-4.jpeg',
fit: BoxFit.cover,
)),
),
),
])))
]))));
}
}

Implementing transitions in a BottomSheet

I'm trying to implement the following design, but I can't seem to get my head around the way I should do it :P
I was thinking about using a BottomSheet displayed via the showModalBottomSheet function, but I can't figure out how to implement the transitions (I'd use a FadeTransition for the fade effect, no idea for the the height-changing effect though)
What I got so far :
import 'package:flutter/material.dart';
import 'dart:math';
class Setup extends StatefulWidget {
final Widget child;
const Setup(this.child);
#override
_SetupState createState() => _SetupState();
}
class MyCurve extends Curve {
#override
double transform(double t) => -pow(t, 2) + 1;
}
class _SetupState extends State<Setup> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> opacityAnimation;
int i = 0;
#override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 500));
opacityAnimation = CurvedAnimation(
parent: Tween<double>(begin: 1, end: 0).animate(_controller),
curve: Curves.easeInOutExpo);
}
#override
Widget build(BuildContext context) {
return BottomSheet(
enableDrag: false,
elevation: 16,
backgroundColor: Colors.transparent,
builder: (_) => Container(
margin: EdgeInsets.all(8),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(16)),
child: Material(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
child: FadeTransition(
opacity: opacityAnimation,
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
widget.child,
Container(
height: 10,
),
RaisedButton(
child: Text("Next"),
onPressed: () {
_controller.forward().then((_) {
_controller.reverse();
});
},
)
],
)),
)),
),
onClosing: () {},
);
}
}
As you can see, I just got the fade animation working, and got none of the routing or height transition done.
Why complicate things when you can achieve the same using AnimatedContainer and AnimateCrossFade.
Just for your information
class BS extends StatefulWidget {
_BS createState() => _BS();
}
class _BS extends State<BS> {
bool _showSecond = false;
#override
Widget build(BuildContext context) {
return BottomSheet(
onClosing: () {},
builder: (BuildContext context) => AnimatedContainer(
margin: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(30)),
child: AnimatedCrossFade(
firstChild: Container(
constraints: BoxConstraints.expand(
height: MediaQuery.of(context).size.height - 200),
//remove constraint and add your widget hierarchy as a child for first view
padding: EdgeInsets.all(20),
child: Align(
alignment: Alignment.bottomCenter,
child: RaisedButton(
onPressed: () => setState(() => _showSecond = true),
padding: EdgeInsets.all(15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Suivant"),
],
),
),
),
),
secondChild: Container(
constraints: BoxConstraints.expand(
height: MediaQuery.of(context).size.height / 3),
//remove constraint and add your widget hierarchy as a child for second view
padding: EdgeInsets.all(20),
child: Align(
alignment: Alignment.bottomCenter,
child: RaisedButton(
onPressed: () => setState(() => _showSecond = false),
color: Colors.green,
padding: EdgeInsets.all(15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("ok"),
],
),
),
),
),
crossFadeState: _showSecond
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: Duration(milliseconds: 400)),
duration: Duration(milliseconds: 400),
),
);
}
}
Since the BottomNavigationSheet's height is based on the height of it's content, you could easily animate it.
Use to Container inside the BottomSheet an give it the height it needs. The height itself can be animated by creating an AnimationController with begin and end set to values you want the height be and set the state. Then just start the animation with the opacity-animation.
containerHeight = CurvedAnimation(
parent: Tween<double>(begin: 350, end: 200).animate(_controller)..addListener(() {setState(() {});});,
curve: Curves.easeInOutExpo);
This should do the work.

How to create a transparent UI in flutter?

I want to create a tranparent UI in flutter.
Can you help me with the code?
Here is the link to the stuff I need.
https://dribbble.com/shots/3958928-Wikipedia-App/attachments/904403
https://dribbble.com/shots/1081917-WhereTO-App
https://dribbble.com/shots/1539644-App-Mockup
https://dribbble.com/shots/1254375-Events-More/attachments/171069
This example my help to resolve your problem
Code Snippet
Widget build(BuildContext context) {
List list = ['Introduction','Early life', 'Non-Film work', '2012-present', 'Controversy'];
return new Container(
child: new Stack(
fit: StackFit.expand,
children: <Widget>[
new Image.asset('assets/bg_img.jpg', fit: BoxFit.fitHeight,),
new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
elevation: 0.0,
backgroundColor: const Color(0xFFB4C56C).withOpacity(0.5),
),
backgroundColor: Colors.transparent,
body: new Center(
child: new Center(
child: new BackdropFilter(
filter: new ui.ImageFilter.blur(
sigmaX: 6.0,
sigmaY: 6.0,
),
child: new Container(
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: const Color(0xFFB4C56C).withOpacity(0.01),
borderRadius: BorderRadius.all(Radius.circular(50.0)),
),
child: new Container(child: ListView.builder(itemBuilder: (contex, index){
return index == 0?new Container(
height: 50.0,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 12.0),
decoration: BoxDecoration(
color: const Color(0xFFB4C56C).withOpacity(0.7),
borderRadius: BorderRadius.all(Radius.circular(25.0)),
boxShadow: [new BoxShadow(color: Colors.black12,offset: new Offset(2.0, 2.0), blurRadius: 2.0 )]
),child: new Row(children: <Widget>[
new Icon(Icons.info, color: Colors.white,),
new SizedBox(width: 8.0),
new Text(list[index], style: TextStyle(color: Colors.white70, fontSize: 18.0))
],),
):new ListTile(title: new Text(list[index], style: TextStyle(color: Colors.white),), leading: new Text('${index}',
style: TextStyle(color: const Color(0xFFB4C56C), fontSize: 18.0)),);
}, itemCount: list.length,),),
),
),
),
),
)
],),
);
}
Complete source code can be dowloaded from here blue_effect
You can override PageRoute like this
import 'package:flutter/cupertino.dart';
class TransparentRoute extends PageRoute<void> {
TransparentRoute({
#required this.builder,
RouteSettings settings,
}) : assert(builder != null),
super(settings: settings, fullscreenDialog: false);
final WidgetBuilder builder;
#override
bool get opaque => false;
#override
Color get barrierColor => null;
#override
String get barrierLabel => null;
#override
bool get maintainState => true;
#override
Duration get transitionDuration => Duration(milliseconds: 350);
#override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
final result = builder(context);
return FadeTransition(
opacity: Tween<double>(begin: 0, end: 1).animate(animation),
child: Semantics(
scopesRoute: true,
explicitChildNodes: true,
child: result,
),
);
}
}
/// And you can push like this
Navigator.of(context).push(
TransparentRoute(
builder: (BuildContext
context) =>
TransParentView()));
///New container to push
class TransParentView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black.withOpacity(0.6),
body: Padding(
padding: const EdgeInsets.all(27.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
height: 700,
width: MediaQuery.of(context).size.width,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: 60,
),
Container(
width: 160,
height: 100,
),
Container(
height: 290,
width: 250,
),
Container(
height: 150,
),
],
),
),
),
),
);
}
}
Hope this will help.
Just surround the widget or widget tree you want to make transparent with an Opacity widget and specify the opacity value from 0.0 to 1.0
For example:
0.0 means completely invisible,
0.5 means half way transparent,
1.0 means fully visible.

Resources