Slide transition is very slow - animation

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

Related

Flutter :- Align a icon to the right bottom of a container

I tried a column with an aligned icon but it didn't display correctly
If anyone has any idea to help. It would be greatly appreciated. Thank you
This is my code that i tried
List<Widget> temp = [];
listAirline.map((airline) {
listAirlineName.map((item) {
if (airline.name == item) {
temp.add(
Column(
children: <Widget>[
Container(
height: 20,
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.all(Radius.elliptical(100.0, 60.0)),
),
child: Image.asset(
"images/Airlines/" + airline.id + ".jpg",
fit: BoxFit.fitWidth,
),
),
Align(
alignment: Alignment.bottomRight,
child: Icon(
Icons.remove_circle,
color: Colors.white,
),
)
],
),
);
}
}).toList();
}).toList();
return temp;
}```
You need to use the Stack widget for it, i have done similar task with the use of the Stack widget,please check thee below solution
class HomeScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _HomeScreen();
}
}
class _HomeScreen extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Container(
height: 100.0,
child: Align(
alignment: Alignment.topCenter,
child: Stack(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 20.0),
height: MediaQuery.of(context).size.width*0.15,
width: MediaQuery.of(context).size.width*0.4,
child: Container(
margin: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.all(Radius.elliptical(20.0, 20.0)),
),
),
)
,
Positioned(
right: 5.0,
bottom: 0.0,
child:
Icon(
Icons.remove_circle,
color: Colors.red,
),
)
],
),
)));
}
}
And output of the above code is as follow

How to animate AnimatedContainer to fill all available space

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

How to save a "Image" with "text" overlapped on it in firebase storage in flutter?

I have an flutter app,where i am adding a text on a image for creating a meme and then when clicked on the save button only the image is stored in firebase not the text which i have added on the image.i want the whole image with text to be stored in firebase storage..Like this
Following is the code i have already tried..
import 'dart:io';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path/path.dart';
import 'package:flutter/material.dart';
import 'package:meme_maker/image_picker_handler.dart';
import 'package:meme_maker/image_picker_dialog.dart';
import 'categories.dart';
import 'uploadpost.dart';
import 'main.dart';
class HomeScreen extends StatefulWidget {
HomeScreen({Key key, this.title}) : super(key: key);
final String title;
#override
_HomeScreenState createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with TickerProviderStateMixin,ImagePickerListener{
File _image;
AnimationController _controller;
ImagePickerHandler imagePicker;
int _counter = 0;
void _incrementCounter() {
setState(
() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
imagePicker=new ImagePickerHandler(this,_controller);
imagePicker.init();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
Future uploadPic(BuildContext context) async{
String fileName = basename(_image.path);
StorageReference firebaseStorageRef = FirebaseStorage.instance.ref().child(fileName);
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image,);
StorageTaskSnapshot taskSnapshot=await uploadTask.onComplete;
setState(() {
print("Profile Picture uploaded");
Scaffold.of(context).showSnackBar(SnackBar(content: Text('Profile Picture Uploaded')));
}
);
}
return new Scaffold(
resizeToAvoidBottomInset : false,
appBar: new AppBar(
title: new Text(widget.title,
style: new TextStyle(
color: Colors.white
),
),
),
body: new GestureDetector(
onTap: () => imagePicker.showDialog(context),
child: new Center(
child: _image == null
? new Stack(
children: <Widget>[
new Center(
child: new CircleAvatar(
radius: 80.0,
backgroundColor: const Color(0xFF778899),
),
),
new Center(
child: new Image.asset("assets/images/photo_camera.png"),
),
],
)
:new Stack(
children: <Widget>[
new Container(
height: 400.0,
width: 400.0,
decoration: new BoxDecoration(
color: const Color(0xff7c94b6
),
image: new DecorationImage(
image: new ExactAssetImage(_image.path),
fit: BoxFit.cover,
),
border:
Border.all(
color: Colors.lightBlueAccent, width: 5.0
),
borderRadius:
new BorderRadius.all(
const Radius.circular(10.0)
),
),
),
HomePages(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Container(
child:new Align(
alignment:Alignment.bottomLeft,
child: RaisedButton(
elevation: 5,
color: Colors.red,
child: Text("Done"),
onPressed:(
)
{
uploadPic(context);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyApp()),
);
//UploadStateScreen();
},
),
),
),
],
),
//HomePages(),
],
)
),
),
);
}
#override
userImage(File _image) {
setState(() {
this._image = _image;
//HomePages();
}
);
}
}
class HomePages extends StatefulWidget {
#override
_HomePagesState createState() => _HomePagesState();
}
class _HomePagesState extends State<HomePages> {
Offset offset = Offset.zero;
File _image;
#override
Widget build(BuildContext context) {
return Container(
child: Positioned(
left: offset.dx,
top: offset.dy,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
offset = Offset(
offset.dx + details.delta.dx, offset.dy + details.delta.dy
);
}
);
},
child: SizedBox(
width: 300,
height: 300,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: TextField(
keyboardType: TextInputType.text,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
color: Colors.white),
decoration: InputDecoration(
//Add th Hint text here.
hintText: "Enter Text",
hintStyle: TextStyle(
fontSize: 30.0, color: Colors.white
),
// border: OutlineInputBorder( borderSide: BorderSide(color: Colors.red, width:
15.0)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent, width: 0.0),
),
),
),
),
),
),
),
),
);
}
}
If you want the text to be editable even after saving it to firebase, you cannot relay only on the storage tool because it only saves files and text is not a file. You will have to use the firebase firestore or firebase real-time database. So, you need to store the text in the database along with other data like the position of the text inside the image, and the image URL coming from the storage.
But if the text should not be editable after saving, you should search for a way to make the text part of the image itself.

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