How to fix "The Method[] was called on null" - flutter

I was trying to make a class for scanning barcodes with "fast_qr_reader_view: ^0.1.5" dependencies. But when I call this class on my main.dart this error came out "NoSuchMethodError: The method[] was called on null.Receiver:null. Tried calling:"
I already tried writing on the main.dart and works, but when Im calling it from a different class doesn't work
This is my code that shows me the error main.dart
import 'package:flutter/material.dart';
import 'RegistroTrajetaOCedulaWidget.dart';
import 'package:pay_id/Screens/testScan.dart';
import 'Screens/dashboard.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scan();
}
}
testScan.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:fast_qr_reader_view/fast_qr_reader_view.dart';
import 'package:lamp/lamp.dart';
List<CameraDescription> cameras;
Future<Null> main() async {
// Fetch the available cameras before initializing the app.
try {
cameras = await availableCameras();
} on QRReaderException catch (e) {
logError(e.code, e.description);
}
runApp(new Scan());
}
void logError(String code, String message) =>
print('Error: $code\nError Message: $message');
class Scan extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<Scan> with SingleTickerProviderStateMixin {
QRReaderController controller;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
AnimationController animationController;
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 3),
);
animationController.addListener(() {
this.setState(() {});
});
animationController.forward();
verticalPosition = Tween<double>(begin: 0.0, end: 300.0).animate(
CurvedAnimation(parent: animationController, curve: Curves.linear))
..addStatusListener((state) {
if (state == AnimationStatus.completed) {
animationController.reverse();
} else if (state == AnimationStatus.dismissed) {
animationController.forward();
}
});
// pick the first available camera
onNewCameraSelected(cameras[0]);
}
Animation<double> verticalPosition;
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: const Text('Prueba escaner'),
),
floatingActionButton: FloatingActionButton(
child: new Icon(Icons.check),
onPressed: () {
Lamp.turnOn();
},
),
body: Stack(
children: <Widget>[
new Container(
child: new Padding(
padding: const EdgeInsets.all(0.0),
child: new Center(
child: _cameraPreviewWidget(),
),
),
),
Center(
child: Stack(
children: <Widget>[
SizedBox(
height: 300.0,
width: 300.0,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.red, width: 2.0)),
),
),
Positioned(
top: verticalPosition.value,
child: Container(
width: 300.0,
height: 2.0,
color: Colors.red,
),
)
],
),
),
],
),
);
}
/// Display the preview from the camera (or a message if the preview is not available).
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'No camera selected',
style: const TextStyle(
color: Colors.white,
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new QRReaderPreview(controller),
);
}
}
void onCodeRead(dynamic value) {
showInSnackBar(value.toString());
// ... do something
// wait 5 seconds then start scanning again.
new Future.delayed(const Duration(seconds: 5), controller.startScanning);
}
void onNewCameraSelected(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = new QRReaderController(cameraDescription,
ResolutionPreset.high, [CodeFormat.qr, CodeFormat.pdf417], onCodeRead);
// If the controller is updated then update the UI.
controller.addListener(() {
if (mounted) setState(() {});
if (controller.value.hasError) {
showInSnackBar('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on QRReaderException catch (e) {
logError(e.code, e.description);
showInSnackBar('Error: ${e.code}\n${e.description}');
}
if (mounted) {
setState(() {});
controller.startScanning();
}
}
void showInSnackBar(String message) {
_scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(message)));
}
}

cameras did not init
you can init cameras in testScan.dart directly
_asyncMethod() async {
cameras = await availableCameras();
onNewCameraSelected(cameras[0]);
print('camera ${cameras.length}');
}
#override
void initState() {
super.initState();
...
_asyncMethod();
}
demo for init cameras in testScan.dart directly
fulll test demo for testScan.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:fast_qr_reader_view/fast_qr_reader_view.dart';
import 'package:lamp/lamp.dart';
List<CameraDescription> cameras;
/*Future<Null> main() async {
// Fetch the available cameras before initializing the app.
try {
cameras = await availableCameras();
} on QRReaderException catch (e) {
logError(e.code, e.description);
}
runApp(new Scan());
}*/
void logError(String code, String message) =>
print('Error: $code\nError Message: $message');
class Scan extends StatefulWidget {
#override
_ScanState createState() => new _ScanState();
}
class _ScanState extends State<Scan> with SingleTickerProviderStateMixin {
QRReaderController controller;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
AnimationController animationController;
_asyncMethod() async {
cameras = await availableCameras();
onNewCameraSelected(cameras[0]);
print('camera ${cameras.length}');
}
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 3),
);
animationController.addListener(() {
this.setState(() {});
});
animationController.forward();
verticalPosition = Tween<double>(begin: 0.0, end: 300.0).animate(
CurvedAnimation(parent: animationController, curve: Curves.linear))
..addStatusListener((state) {
if (state == AnimationStatus.completed) {
animationController.reverse();
} else if (state == AnimationStatus.dismissed) {
animationController.forward();
}
});
// pick the first available camera
_asyncMethod();
}
Animation<double> verticalPosition;
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: const Text('Prueba escaner'),
),
floatingActionButton: FloatingActionButton(
child: new Icon(Icons.check),
onPressed: () {
Lamp.turnOn();
},
),
body: Stack(
children: <Widget>[
new Container(
child: new Padding(
padding: const EdgeInsets.all(0.0),
child: new Center(
child: _cameraPreviewWidget(),
),
),
),
Center(
child: Stack(
children: <Widget>[
SizedBox(
height: 300.0,
width: 300.0,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.red, width: 2.0)),
),
),
Positioned(
top: verticalPosition.value,
child: Container(
width: 300.0,
height: 2.0,
color: Colors.red,
),
)
],
),
),
],
),
);
}
/// Display the preview from the camera (or a message if the preview is not available).
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'No camera selected',
style: const TextStyle(
color: Colors.white,
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new QRReaderPreview(controller),
);
}
}
void onCodeRead(dynamic value) {
showInSnackBar(value.toString());
// ... do something
// wait 5 seconds then start scanning again.
new Future.delayed(const Duration(seconds: 5), controller.startScanning);
}
void onNewCameraSelected(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = new QRReaderController(cameraDescription,
ResolutionPreset.high, [CodeFormat.qr, CodeFormat.pdf417], onCodeRead);
// If the controller is updated then update the UI.
controller.addListener(() {
if (mounted) setState(() {});
if (controller.value.hasError) {
showInSnackBar('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on QRReaderException catch (e) {
logError(e.code, e.description);
showInSnackBar('Error: ${e.code}\n${e.description}');
}
if (mounted) {
setState(() {});
controller.startScanning();
}
}
void showInSnackBar(String message) {
_scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(message)));
}
}

Related

Data not loading after using annimation

I am making a chat app using flutter. It is loading data from firestore but when I am using annimation in the drawer the chat's aren't loading I don't know the reason if i comment out the animation in the chat screen it works and it works also if comment out if block which contain connection state.waiting without commenting annimation
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:my_flutter_app/chat/messages.dart';
import 'package:my_flutter_app/chat/new_message.dart';
class ChatScreen extends StatefulWidget {
const ChatScreen({Key? key}) : super(key: key);
#override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> with SingleTickerProviderStateMixin{
late AnimationController controller;
late Animation animation;
#override
void initState() {
super.initState();
controller=AnimationController(
duration: Duration(seconds: 2),
vsync: this);
animation=CurvedAnimation(parent: controller, curve: Curves.decelerate);
controller.forward();
animation.addStatusListener((status) {
if(status==AnimationStatus.completed){
controller.reverse(from: 1.0);
}else if(status==AnimationStatus.dismissed){
controller.forward();
}
});
controller.addListener(() {
setState(() {
animation.value;
});
});
}
#override
void dispose() {
super.dispose();
controller.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
margin: EdgeInsets.only(top: 50),
padding: EdgeInsets.all(15),
child: CircleAvatar(backgroundImage: AssetImage('assets/profile.png'),radius: 60),),
Container(
child: Image.asset('assets/welcome.png'),
height: animation.value*100,
),
InkWell(
onTap: (){
showCupertinoDialog(context: context, builder: (context)=>CupertinoAlertDialog(
title: Text('Alert'),
content: Text('Are you sure you want to logout?'),
actions: [
CupertinoDialogAction(child: Text('Yes'),onPressed: (){
FirebaseAuth.instance.signOut();
Navigator.pop(context);
},),
CupertinoDialogAction(child: Text('No'),onPressed: (){
Navigator.pop(context);
},)
],
));
//FirebaseAuth.instance.signOut();
},
child: ListTile(leading: Icon(Icons.logout,color: Colors.white),
title: Text('LOGOUT',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),),
tileColor: Colors.red,),
)
],
),
),
appBar: AppBar(title: Text('Chats'),centerTitle: true,backgroundColor: Colors.green),
body: Container(
child: Column(
children: [
Expanded(child: Messages()),
NewMessage(),
],
),
),
);
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:my_flutter_app/chat/mesui.dart';
class Messages extends StatefulWidget {
const Messages({Key? key}) : super(key: key);
#override
State<Messages> createState() => _MessagesState();
}
class _MessagesState extends State<Messages> {
final auth=FirebaseAuth.instance;
User ?cuser;
#override
void initState() {
// TODO: implement initState
super.initState();
getCurrentUser();
}
void getCurrentUser(){
try {
final user = auth.currentUser;
if (user != null) {
cuser = user;
}
}
catch(e){
print(e);
}
}
#override
Widget build(BuildContext context) {
return StreamBuilder(stream: FirebaseFirestore.instance.collection('chat').orderBy('messaged_on',descending: true).snapshots(),
builder: (context,snaps) {
if(snaps.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
final documents=snaps.data!.docs;
final nowperson=cuser!.email;
return ListView.builder(
reverse: true,
itemBuilder: (ctx,index){
final sender=documents[index]['email'];
bool isMe= sender==nowperson;
return Mesui(documents[index]['text'],isMe);
},
itemCount: documents.length,);
},
);
}
}

How to create flutter Custom Curved Navigation Drawer

I am creating custom navigation drawer. I want add curved animation onItemSelected.
But I have no idea how to create curved animation effect. I have tried many plugins but could not find plugin which related with this design. Here is my example code
import 'package:flutter/material.dart';
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
void main() {
runApp(
MaterialApp(
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
List<bool> selected = [true, false, false, false, false];
class _MyAppState extends State<MyApp> {
List<IconData> icon = [
Feather.wind,
Feather.folder,
Feather.monitor,
Feather.lock,
Feather.mail,
];
void select(int n) {
for (int i = 0; i < 5; i++) {
if (i == n) {
selected[i] = true;
} else {
selected[i] = false;
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Container(
color: Colors.white,
),
Container(
margin: EdgeInsets.all(8.0),
height: MediaQuery.of(context).size.height,
width: 101.0,
decoration: BoxDecoration(
color: Color(0xff332A7C),
borderRadius: BorderRadius.circular(20.0),
),
child: Stack(
children: [
Positioned(
top: 110,
child: Column(
children: icon
.map(
(e) => NavBarItem(
icon: e,
selected: selected[icon.indexOf(e)],
onTap: () {
setState(() {
select(icon.indexOf(e));
});
},
),
)
.toList(),
),
),
],
),
),
],
),
);
}
}
class NavBarItem extends StatefulWidget {
final IconData icon;
final Function onTap;
final bool selected;
NavBarItem({
this.icon,
this.onTap,
this.selected,
});
#override
_NavBarItemState createState() => _NavBarItemState();
}
class _NavBarItemState extends State<NavBarItem> with TickerProviderStateMixin {
AnimationController _controller1;
AnimationController _controller2;
Animation<double> _anim1;
Animation<double> _anim2;
Animation<double> _anim3;
Animation<Color> _color;
bool hovered = false;
#override
void initState() {
super.initState();
_controller1 = AnimationController(
vsync: this,
duration: Duration(milliseconds: 250),
);
_controller2 = AnimationController(
vsync: this,
duration: Duration(milliseconds: 275),
);
_anim1 = Tween(begin: 101.0, end: 75.0).animate(_controller1);
_anim2 = Tween(begin: 101.0, end: 25.0).animate(_controller2);
_anim3 = Tween(begin: 101.0, end: 50.0).animate(_controller2);
_color = ColorTween(end: Color(0xff332a7c), begin: Colors.white)
.animate(_controller2);
_controller1.addListener(() {
setState(() {});
});
_controller2.addListener(() {
setState(() {});
});
}
#override
void didUpdateWidget(NavBarItem oldWidget) {
super.didUpdateWidget(oldWidget);
if (!widget.selected) {
Future.delayed(Duration(milliseconds: 10), () {
//_controller1.reverse();
});
_controller1.reverse();
_controller2.reverse();
} else {
_controller1.forward();
_controller2.forward();
Future.delayed(Duration(milliseconds: 10), () {
//_controller2.forward();
});
}
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
widget.onTap();
},
child: MouseRegion(
onEnter: (value) {
setState(() {
hovered = true;
});
},
onExit: (value) {
setState(() {
hovered = false;
});
},
child: Container(
width: 101.0,
color:
hovered && !widget.selected ? Colors.white12 : Colors.transparent,
child: Stack(
children: [
Container(
height: 80.0,
width: 101.0,
child: Center(
child: Icon(
widget.icon,
color: _color.value,
size: 18.0,
),
),
),
],
),
),
),
);
}
}
I want create Navigation Drawer like this image given in above example. How can I achieve this please help me for it Thank you in advance.

Preview photo after camera takes picture

When a user takes a photo, I want to send it to the photo_preview screen, which gives the user the chance to take another photo.
This page is as follows:
import 'package:flutter/material.dart';
import 'dart:io';
class photo_previewScreen extends StatelessWidget {
final String imagePath;
const photo_previewScreen({Key key, this.imagePath}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Display the Picture')),
body: Image.file(File(imagePath)),
);
}
}
On my current camera page, what's the best way for me to send the photo to the above page?
When the take picture button is pressed, this is what is currently happening:
onPressed: () {
_openGallery();
Navigator.pop(context);
},
EDIT: Full page with edits from the answer
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:io';
import 'package:stumble/pages/PhotoPreviewScreen.dart';
class Camera extends StatefulWidget {
Function setData;
Camera({Key key, this.setData}) : super(key: key);
#override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<Camera> {
CameraController controller;
List cameras;
int selectedCameraIndex;
String imgPath;
var image;
takePicture;
Future _openGallery() async {
image = await controller.takePicture();
if (widget.setData != null) {
widget.setData(File(image.path));
}
}
#override
void initState() {
super.initState();
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.length > 0) {
setState(() {
selectedCameraIndex = 0;
});
_initCameraController(cameras[selectedCameraIndex]).then((void v) {});
} else {
print('No camera available');
}
}).catchError((err) {
print('Error :${err.code}Error message : ${err.message}');
});
}
Future _initCameraController(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = CameraController(cameraDescription, ResolutionPreset.high);
controller.addListener(() {
if (mounted) {
setState(() {});
}
if (controller.value.hasError) {
print('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on CameraException catch (e) {}
if (mounted) {
setState(() {});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: _cameraPreviewWidget(),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 120,
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[_cameraControlWidget(context), Spacer()],
),
),
)
],
),
),
),
);
}
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Loading',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
);
}
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(children: <Widget>[
Positioned.fill(
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),
]);
}
Widget _cameraControlWidget(context) {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FloatingActionButton(
child: Icon(
Icons.center_focus_strong,
size: 39,
color: Color(0xffffffff),
),
backgroundColor: Color(0xff33333D),
onPressed: () async {
var result = await takePicture();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PhotoPreviewScreen(
imagePath: result,
),
),
);
})
],
),
),
);
}
}
I am getting the error that
'The method 'takePicture isn't defined for the type '_CameraScreenState'
This despite takePicture(); being defined.
You can navigate to the preview screen on clicking the take picture button, passing the image path:
void onTakePictureButtonPressed() async {
var result = await takePicture();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PhotoPreviewScreen(
imagePath: result,
),
),
);
}
Future<String> takePicture() async {
if (!controller.value.isInitialized) {
showErrorFlushbar(context, 'Error: select a camera first.');
return null;
}
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/ompariwar';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
if (controller.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
}
try {
await controller.takePicture(filePath);
} on CameraException catch (e) {
print(e);
return null;
}
return filePath;
}
In the preview screen, you can do this:
class PhotoPreviewScreen extends StatelessWidget {
final String imagePath;
const PhotoPreviewScreen({Key key, this.imagePath}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.pop(context), // Go back to the camera to take the picture again
child: Icon(Icons.camera_alt),
),
appBar: AppBar(title: Text('Display the Picture')),
body: Column(
children: [
Expanded(child: Image.file(File(imagePath))),
SomeButton(), // Add a button to send the image to server or go back to home screen here
],
),
);
}
}
Btw it's a convention to name your class/ Widget name in UpperCamelCase. Read more on this Dart style guide for clean code.

Camera preview stretched vertically

My camera preview is currently stretched vertically as per the screenshot attached.
The code to the camera page is below, does anyone know how to adjust the code so that the camera preview does not appear to be stretched?
I need it to work for iOS and Android, and for every device.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:io';
import 'package:flutter/services.dart';
class Camera extends StatefulWidget {
Function setData;
Camera({Key key, this.setData}) : super(key: key);
#override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<Camera> {
CameraController controller;
List cameras;
int selectedCameraIndex;
String imgPath;
var image;
Future _openGallery() async {
image = await controller.takePicture();
if (widget.setData != null) {
widget.setData(File(image.path));
}
}
#override
void initState() {
super.initState();
SystemChrome.setEnabledSystemUIOverlays([]);
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.length > 0) {
setState(() {
selectedCameraIndex = 0;
});
_initCameraController(cameras[selectedCameraIndex]).then((void v) {});
} else {
print('No camera available');
}
}).catchError((err) {
print('Error :${err.code}Error message : ${err.message}');
});
}
Future _initCameraController(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
controller = CameraController(cameraDescription, ResolutionPreset.high);
controller.addListener(() {
if (mounted) {
setState(() {});
}
if (controller.value.hasError) {
print('Camera error ${controller.value.errorDescription}');
}
});
try {
await controller.initialize();
} on CameraException catch (e) {}
if (mounted) {
setState(() {});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Stack(
children: <Widget>[
_cameraPreviewWidget(),
_cameraControlWidget(context)
],
),
),
);
}
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Loading',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
);
}
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(children: <Widget>[
Positioned.fill(
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),
]);
}
Widget _cameraControlWidget(context) {
return Container(
child: Align(
alignment: Alignment.center,
child: FloatingActionButton(
child: Icon(
Icons.center_focus_strong,
size: 39,
color: Color(0xd),
),
backgroundColor: Color(0xff33333D),
onPressed: () {
_openGallery();
Navigator.pop(context);
},
)
));
}
}
and here is the image as to how it is rendering. The button in the middle takes the photo.
I have struggled with the camera preview in Flutter as well. It is a pain to work with. This is what I am using right now. Hopefully it will help you
class CameraPreview extends StatelessWidget {
const CameraPreview({Key? key, this._cameraController}) : super(key: key);
final CameraController _cameraController;
#override
Widget build(BuildContext context) {
return ClipRect(
child: OverflowBox(
alignment: Alignment.center,
child: FittedBox(
fit: BoxFit.cover,
child: SizedBox(
height: 1,
child: AspectRatio(
aspectRatio: 1 / _cameraController.value.aspectRatio,
child: CameraPreview(_cameraCcontroller),
),
),
),
),
);
}
}

How can I change ColorTween begin or end color with setState?

This is a widget for my quiz app. I am currently working on the quiz option button.
I want it to blink green or red whether the answer is true or not.
But it's not working. I tried different things but I couldn't succeed.
import 'package:flutter/material.dart';
class TestButton extends StatefulWidget {
TestButton({this.text, this.color, this.onPressed});
final Function onPressed;
final Color color;
final String text;
#override
_TestButtonState createState() => _TestButtonState();
}
class _TestButtonState extends State<TestButton> with TickerProviderStateMixin {
AnimationController _animationController;
Animation _animation;
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 400));
_animation = ColorTween(begin: Colors.transparent, end: widget.color)
.animate(CurvedAnimation(curve: Curves.decelerate, parent: _animationController))
..addListener(() {
setState(() {
});
});
_animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.reverse();
} else if (status == AnimationStatus.dismissed) {
_animationController.forward();
}
});
_animationController.forward();
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return SizedBox(
width: width / 1.3,
child: InkWell(
borderRadius: BorderRadius.circular(30),
onTap: widget.onPressed,
child: Container(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(width / 20),
decoration: BoxDecoration(
color: _animation.value,
border: Border.all(color: Colors.white38),
borderRadius: BorderRadius.circular(20)),
child: Text(
widget.text,
style: TextStyle(fontSize: 16, fontFamily: "Fondamento"),
),
),
),
),
);
}
}
And this is the usage of the button. I am applying a setState function but it doesn't make sense. The problem is that the animation works but the setState function doesn't change the color value in the ColorTween
TestButton(
text: question.optionA,
color: colorA,//Colors.transparent
onPressed: () {
if (canTap) {
canTap = false;
if (question.answer == 1) {
setState(() {
colorA = Colors.green;
});
} else {
setState(() {
colorA = Colors.red;
});
}
}
},
),
Remove this part:
..addListener(() {
setState(() {
});
});
And use AnimatedBuilder like this:
return SizedBox(
width: width / 1.3,
child: InkWell(
borderRadius: BorderRadius.circular(30),
onTap: widget.onPressed,
child: Container(
child: AnimatedBuilder(
animation: _animationController,
builder: (_, __) => Container(
alignment: Alignment.center,
padding: EdgeInsets.all(width / 20),
decoration: BoxDecoration(
color: _animationController.value,
border: Border.all(color: Colors.white38),
borderRadius: BorderRadius.circular(20)),
child: Text(
widget.text,
style: TextStyle(fontSize: 16, fontFamily: "Fondamento"),
),
)
),
),
),
);
You can copy paste run full code below
You can use didUpdateWidget to reset _animation
In working demo, when click button, color changes from red to green
#override
void didUpdateWidget(covariant TestButton oldWidget) {
if (oldWidget.color != widget.color) {
_animation = ColorTween(begin: Colors.transparent, end: widget.color)
.animate(CurvedAnimation(
curve: Curves.decelerate, parent: _animationController))
..addListener(() {
setState(() {});
});
}
super.didUpdateWidget(oldWidget);
}
working demo
full code
import 'package:flutter/material.dart';
class TestButton extends StatefulWidget {
TestButton({this.text, this.color, this.onPressed});
final Function onPressed;
final Color color;
final String text;
#override
_TestButtonState createState() => _TestButtonState();
}
class _TestButtonState extends State<TestButton> with TickerProviderStateMixin {
AnimationController _animationController;
Animation _animation;
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 400));
_animation = ColorTween(begin: Colors.transparent, end: widget.color)
.animate(CurvedAnimation(
curve: Curves.decelerate, parent: _animationController))
..addListener(() {
setState(() {});
});
_animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.reverse();
} else if (status == AnimationStatus.dismissed) {
_animationController.forward();
}
});
_animationController.forward();
}
#override
void didUpdateWidget(covariant TestButton oldWidget) {
if (oldWidget.color != widget.color) {
_animation = ColorTween(begin: Colors.transparent, end: widget.color)
.animate(CurvedAnimation(
curve: Curves.decelerate, parent: _animationController))
..addListener(() {
setState(() {});
});
}
super.didUpdateWidget(oldWidget);
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return SizedBox(
width: width / 1.3,
child: InkWell(
borderRadius: BorderRadius.circular(30),
onTap: widget.onPressed,
child: Container(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(width / 20),
decoration: BoxDecoration(
color: _animation.value,
border: Border.all(color: Colors.white38),
borderRadius: BorderRadius.circular(20)),
child: Text(
widget.text,
style: TextStyle(fontSize: 16, fontFamily: "Fondamento"),
),
),
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Color colorA = Colors.red;
bool canTap = true;
int answer = 1;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TestButton(
text: "question.optionA",
color: colorA, //Colors.transparent
onPressed: () {
if (canTap) {
canTap = false;
if (answer == 1) {
setState(() {
colorA = Colors.green;
});
} else {
setState(() {
colorA = Colors.red;
});
}
}
},
),
],
),
),
);
}
}