I'am noob of flutter and i want a create some apps. This is my main screen with animated container.
import 'package:flutter/material.dart';
import "./loginmenu.dart";
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color.fromRGBO(197, 197, 187, 1),
body: AnimatedContainer(
duration: Duration(milliseconds: 350),
width: double.infinity,
height: double.infinity,
child: Image(image: AssetImage("assets/images/Babapps-logos.jpeg")),
onEnd: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => loginscreen()),
),
),
),
);
}
}
when animation duration finish i want go new screen.
import 'package:flutter/material.dart';
class loginscreen extends StatefulWidget {
const loginscreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
Container(width: double.infinity, margin: EdgeInsets.all(130)),
Container(
width: double.infinity,
margin: EdgeInsets.all(5),
child: Center(
child:
Text("Welcome Diet&Life", style: TextStyle(fontSize: 19)),
),
),
Container(
width: 320,
margin: EdgeInsets.all(5),
child: Center(
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(), hintText: "Username"),
),
),
),
Container(
width: 320,
margin: EdgeInsets.all(5),
child: Center(
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(), hintText: "Password"),
)),
),
Container(
child: Center(
child: RaisedButton(
child: Text("Login"),
onPressed: null,
),
),
),
Container(
margin: EdgeInsets.all(10),
child: Center(
child: new InkWell(
child: Text("Don't have an account?"), onTap: null),
),
)
],
),
),
);
}
#override
State<StatefulWidget> createState() {
// TODO: implement createState
throw UnimplementedError();
}
}
but when I run this code, the animation does not go to the other screen even though it expires. Am I on the right track or do I have to work with setstate?
There is nothing changing on Container, therefor animation onEnd never gets call.
You need to change something inside the container in order to animate it.
If you just like to navigate after some delay, Just use Future.delayed then navigate.
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return const MaterialApp(home: StartPage());
}
}
class StartPage extends StatefulWidget {
const StartPage({Key? key}) : super(key: key);
#override
State<StartPage> createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
Color containerColor = Colors.cyanAccent;
#override
void initState() {
super.initState();
_nextPage();
}
/// just nevigate
_nextPage() async {
Future.delayed(Duration(seconds: 1)).then((value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AnimE(),
),
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
containerColor = Colors.blue;
});
},
),
body: AnimatedContainer(
duration: const Duration(seconds: 2),
color: containerColor,
width: double.infinity,
height: double.infinity,
child: const Text("a"),
onEnd: () {
print("Ebnd"); // paste neviagte by removing init
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => loginscreen(),
// ),
// );
}),
);
}
}
Related
I would like to display last 3 images in the camera roll/gallery/photos from my app. How do I achieve this in Flutter?
Any ideas?
Suppose I want to see the latest images in the DCIM folder. How do we do this?
I hope what you're looking for will be solved by using this package photo_gallery
Never used this package before, but it seems to fit your needs.
Try to use media_picker_widget as its supports presenting specific amount of images from different albums using custom widgets.
Check out the official example:
import 'package:flutter/material.dart';
import 'package:media_picker_widget/media_picker_widget.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: 'Media Picker',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Media> mediaList = [];
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Image Picker'),
),
body: previewList(),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => openImagePicker(context),
),
);
}
Widget previewList() {
return SizedBox(
height: 96,
child: ListView(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
children: List.generate(
mediaList.length,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
height: 80,
width: 80,
child: Image.memory(
mediaList[index].thumbnail,
fit: BoxFit.cover,
),
),
)),
),
);
}
void openImagePicker(BuildContext context) {
// openCamera(onCapture: (image){
// setState(()=> mediaList = [image]);
// });
showModalBottomSheet(
context: context,
builder: (context) {
return MediaPicker(
mediaList: mediaList,
onPick: (selectedList) {
setState(() => mediaList = selectedList);
Navigator.pop(context);
},
onCancel: () => Navigator.pop(context),
mediaCount: MediaCount.multiple,
mediaType: MediaType.image,
decoration: PickerDecoration(
actionBarPosition: ActionBarPosition.top,
blurStrength: 2,
completeText: 'Next',
),
);
});
}
}
I have a MainScreen and SecondScreen. When the drawer item in the MainScreen clicked. It should move to SecondScreen Container widget. But how to do that?
I have set ScrollController for SecondScreen SingleChildScrollView. but how to move to a certain widget?
Create a method in SecondScreen which scroll to the widget?
What if I have 3rd screen which need same functionality.
SecondScreen.dart
import 'package:flutter/material.dart';
ScrollController scrollController = ScrollController();
var containerKey = GlobalKey();
class SecondScreen extends StatefulWidget {
final Key widgetKey;
const SecondScreen({Key key, this.widgetKey}) : super(key: key);
#override
State<SecondScreen> createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
#override
void initState() {
// TODO: implement initState
super.initState();
Scrollable.ensureVisible(
widget.widgetKey,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
controller: scrollController,
child: Column(
children: [
Text('hi'),
Container(
color: Colors.red,
height: 1000,
),
Container(
color: Colors.green,
height: 1000,
),
Container(
key: containerKey,
color: Colors.green,
height: 1000,
),
],
),
),
);
}
}
mainscreen.dart
import 'package:flutter/material.dart';
import 'package:stackoverflow_check/scrollcheck/second_screen.dart';
class MainScreen extends StatelessWidget {
const MainScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: ListView(
children: [
TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SecondScreen(widgetKey: containerKey),
),
);
//scrollController.an
},
child: Text('click'),
)
],
),
),
);
}
}
Main screen
class MainScreen extends StatelessWidget {
const MainScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: ListView(
children: [
TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SecondScreen(widgetNum: 2),
),
);
//scrollController.an
},
child: Text('click'),
)
],
),
),
);
}
}
SecondScreen
class SecondScreen extends StatefulWidget {
final int widgetNum;
const SecondScreen({Key? key, required this.widgetNum}) : super(key: key);
#override
State<SecondScreen> createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
ScrollController scrollController = ScrollController();
var containerKey = GlobalKey();
var container2Key = GlobalKey();
#override
void initState() {
// TODO: implement initState
super.initState();
}
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
Future.delayed(Duration(milliseconds: 100), () {
if (widget.widgetNum == 1) {
Scrollable.ensureVisible(
containerKey.currentContext!,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
} else {
Scrollable.ensureVisible(
container2Key.currentContext!,
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
controller: scrollController,
child: Column(
children: [
Text('hi'),
Container(
color: Colors.red,
height: 1000,
),
Container(
color: Colors.green,
height: 1000,
),
Container(
key: containerKey,
color: Colors.green,
height: 1000,
),
Container(
key: container2Key,
color: Colors.blue,
height: 1000,
),
],
),
),
);
}
}
So we have a Dismissible for confirming/denying a item.
However we have some users that are trying to click/tap on the item.
Our UX team suggested that we then "bounce" the item to show that they have to swipe (and reveal the action fields).
But I don't see any option to do so.
Does anybody have a suggestion what might work for this?
The code I have for now is shown below:
Dismissible(
key: const ValueKey(0),
direction: DismissDirection.horizontal,
child: Container(
margin: EdgeInsets.symmetric(horizontal: 3, vertical: 3),
child: card(),
),
confirmDismiss: (direction) async {
var newStatus = direction == DismissDirection.startToEnd
? OkNokNvt.OK
: OkNokNvt.NOK;
_changeStatus(newStatus);
return false;
},
background: ok(),
secondaryBackground: nok(),
),
The Dismissable doesn't seeem to have this functionality.
Instead, you could use the flutter_slidable package.
Here, you can programmatically open the underlying actions by calling Slideable.of(context)?.open(). No fancy bounce-animation though.
Here's the code:
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bouncing Widget Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Slidable(
key: const Key('key'),
actionPane: const SlidableDrawerActionPane(),
actionExtentRatio: 0.25,
child: Builder(
builder: (context) => GestureDetector(
onTap: () {
Slidable.of(context)
?.open(actionType: SlideActionType.primary);
},
child: Container(
color: Colors.grey,
height: 50,
child: const Center(child: Text('Tap me')),
),
),
),
actions: [
IconSlideAction(
caption: 'Delete',
color: Colors.red,
icon: Icons.delete,
onTap: () => print('remove me from list'),
),
],
dismissal: SlidableDismissal(
onDismissed: (_) => print('remove me from list'),
dragDismissible: true,
child: const SlidableDrawerDismissal(),
),
),
],
),
),
);
}
}
Here is my minimal example which does what you are looking for.
Basically, the GestureDetector onTap callback triggers the animation which has a bouncing-like effect by using a sin function on the _animation.value. The behaviour can be tweeked by changing the parameters cyclesPerAnimation and bounceOffset.
Simply put your Dismissible in the place of the Container and you should be good to go.
environment:
sdk: ">=2.12.0 <3.0.0"
import 'dart:math';
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(
theme: ThemeData.dark(),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late final AnimationController _animation = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
Offset _bounceOffset(double animationValue) {
const cyclesPerAnimation = 2;
const bounceOffset = 10;
return Offset(
0,
sin(animationValue * pi * 2 * cyclesPerAnimation) * bounceOffset,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bouncing Widget Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedBuilder(
animation: _animation,
builder: (context, widget) => Transform.translate(
offset: _bounceOffset(_animation.value),
child: GestureDetector(
onTap: () {
_animation.reset();
_animation.forward();
},
child: Container(
color: Colors.grey,
height: 50,
width: 200,
child: const Center(child: Text('Tap to bounce')),
),
),
),
),
],
),
),
);
}
}
I implement a Room Chat Screen and inside it an animated Container move from left to right and start a again after finish, could someone inform me how to implement it
You need looping animate container, then you can try some Marquee package, such as fast_marquee:
Marquee(
text: 'Some sample text that takes some space.',
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
velocity: 100,
blankSpace: 10,
startPadding: 10,
reverse: true,
bounce: true,
startAfter: const Duration(seconds: 2),
pauseAfterRound: const Duration(seconds: 1),
numberOfRounds: 5,
showFadingOnlyWhenScrolling: false,
fadingEdgeStartFraction: 0.05,
fadingEdgeEndFraction: 0.05,
curve: Curves.easeInOut,
)
OR
try AnimatedPositioned:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatefulWidget(),
),
),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
bool selected = false;
#override
Widget build(BuildContext context) {
return SizedBox(
width: 200,
height: 350,
child: Stack(
children: <Widget>[
AnimatedPositioned(
width: selected ? 200.0 : 50.0,
height: selected ? 50.0 : 200.0,
top: selected ? 50.0 : 150.0,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Container(
color: Colors.blue,
child: const Center(child: Text('Tap me')),
),
),
),
],
),
);
}
}
I am working on a custom dialog called "Alertbox" where the user inserts a name into a textfield and after he pushes the button a function called "addTeam" created a team out of the string.
This is how I created my dialog "Alertbox":
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:trainings_app/config/palette.dart';
class Alertbox extends StatelessWidget {
final Function addTeamFunction;
const Alertbox(this.addTeamFunction);
#override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
elevation: 0,
insetPadding: EdgeInsets.all(10),
child: Center(
child: Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(const Radius.circular(20)),
color: Colors.white,
),
width: 350,
height: 200,
child: Row(
children: [
SizedBox(width: 12),
Expanded(
child: TextField(
textAlign: TextAlign.center,
autofocus: true,
),
),
SizedBox(width: 12),
ElevatedButton(
onPressed: () => addTeamFunction(),
child: const Text('✓'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Palette.orange),
),
),
SizedBox(width: 8),
],
),
),
),
);
}
}
And here I am using it:
void newTeam() {
showDialog<AlertDialog>(
context: context,
builder: (BuildContext context) {
return Alertbox(() {
Navigator.of(context).pop();
});
},
);
}
void addTeam(String name) {
setState(() {
teams.add(name);
});
Navigator.of(context).pop();
sharedPreferences.setStringList('teams', teams);
}
But I can't find a way to parse the input from the textfield into the function "addTeam" where it is needed. Can anyone help me please?
You Should try below code hope its helps you:
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 const MaterialApp(
title: 'Testing',
home: MyCustomForm(),
);
}
}
class MyCustomForm extends StatefulWidget {
const MyCustomForm({Key? key}) : super(key: key);
#override
_MyCustomFormState createState() => _MyCustomFormState();
}
class _MyCustomFormState extends State<MyCustomForm> {
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Retrieve Text Input'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: myController,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(myController.text),
);
},
);
},
tooltip: 'Show the value!',
child: const Icon(Icons.add),
),
);
}
}
Your Screen like ->
Use a TextFormField instead of a TexiField widget contained in a Form widget that has a GlobalKey, which will be useful to you during validation!
How to get the value which is already entered on the keyboard?
Uses a TextEditingController or the onSaved method of the TextFormField.