I'm trying to implement imagepicker library in my app. My app runs without any errors but I can't pick/select images from the album/gallery. On selecting the image the app should display the image in the body but nothing happens. I have to tap on Cancel to go back to the main screen. I should also mention that the console returns null for the print statement print('image: $image');
Kindly help.
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.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(
brightness: Brightness.dark,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File image;
final picker = ImagePicker();
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
image = File(pickedFile.path);
} else {
print('image: $image');
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Picker'),
),
body: Center(
child: image == null
? Text('No image selected.')
: Image.file(image),
),
floatingActionButton: FloatingActionButton(
onPressed: getImage,
tooltip: 'Pick Image',
child: Icon(Icons.add_a_photo),
),
);
}
}
Try with the below code
Future getImage() async {
File pickedFile = await picker.getImage(source: ImageSource.gallery);
if (pickedFile != null) {
setState(() {
image = File(pickedFile.path);
});
} else {
print('image: $image');
}
}
Related
Lets say i have a button. So..
String buttonTitle = "Upload";
Above is the button title.
Now i have set this in my text of the button. When i upload something, i want this text to be Uploaded so i use setState method for that and hence the title of the button will be updated. But let's suppose i have 100s of buttons which just says Upload and later have to be changed to just Uploaded if something has been uploaded using that button, am i going to create 100 Strings here? This approach doesn't seem good enough to me. Is there a better approach for this in flutter ?
Check this widget as you expect . click on main button it will update all button state after 3 second like uploading
class MyHomePages2 extends StatefulWidget {
MyHomePages2({Key? key}) : super(key: key);
var Upload = "Upload";
#override
State<MyHomePages2> createState() => _MyHomePages2State();
}
class _MyHomePages2State extends State<MyHomePages2> {
#override
Widget build(BuildContext context) {
return ListView(
children: [
ElevatedButton(
onPressed: () {
setState(() {
widget.Upload = "upload";
});
Future.delayed(Duration(seconds: 3), () {
setState(() {
widget.Upload = "uploaded";
});
});
},
child: Text("MainUpload")),
...List.generate(
100,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {}, child: Text("$index ${widget.Upload}")),
))
],
);
}
}
SampleCode Dartpad live code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
int myvalue = 0;
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
#override
void initState() {
// functions().then((int value) {
// setState(() {
// myvalue = value;
// });
// future is completed you can perform your task
// });
}
Future<int> functions() async {
// do something here
return Future.value();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: MyHomePages2(),
);
}
}
class MyHomePages2 extends StatefulWidget {
MyHomePages2({Key? key}) : super(key: key);
var Upload = "Upload";
#override
State<MyHomePages2> createState() => _MyHomePages2State();
}
class _MyHomePages2State extends State<MyHomePages2> {
#override
Widget build(BuildContext context) {
return ListView(
children: [
ElevatedButton(
onPressed: () {
setState(() {
widget.Upload = "upload";
});
Future.delayed(Duration(seconds: 3), () {
setState(() {
widget.Upload = "uploaded";
});
});
},
child: Text("MainUpload")),
...List.generate(
100,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {}, child: Text("$index ${widget.Upload}")),
))
],
);
}
}
I am using Webview with WillPopScope, webview internal back button is working fine but on the first page back press is not working.
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SafeArea(child: MyHomePage()),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
InAppWebViewController _controller;
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => canGoBack(context),
child: Scaffold(
body: InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse("https://www.google.com/")),
onWebViewCreated: onWebviewCreated,
),
),
);
}
void onWebviewCreated(InAppWebViewController controller) {
_controller = controller;
}
canGoBack(BuildContext context) async {
if (await _controller.canGoBack()) {
_controller.goBack();
return Future.value(false);
} else {
return Future.value(true);
}
}
}
tried with
canGoBack(BuildContext context) async {
if (await _controller.canGoBack()) {
_controller.goBack();
return Future.value(false);
} else {
Navigator.pop(context, true);
return Future.value(false);
}
}
the issue is showing the black if there is no webview history.
You don't have any previous root and you're using
Navigator.pop(context, true); // in canGoBack function
That's cause to issue. Remove that line and it will work.
I have this event form, it's to create or edit events data. The save button is inside the app bar action, and the form is inside the body. In this project, I have all of the widgets in different files. How do I run the save function inside EventFormForm.dart when I tap the save button inside EventFromAppBar.dart?
This is the structure :
These are my codes :
EventForm.dart
class EventForm extends StatelessWidget {
// Some Code
// Some Const
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: EventFormAppBar(
// Some Params
),
body: EventFormBody(
// Some Params
)
);
}
}
EventFormAppBar.dart
class EventFormAppBar extends PreferredSize{
// Some Code
// Some Const
// Some Code
#override
Widget build(BuildContext context) {
return AppBar(
// Some Code
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {
}
)
]
);
}
}
EventFormBody.dart
class EventFormBody extends StatelessWidget {
// Some Code
// Some Const
#override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: EventFormForm(
// Some Params
),
),
);
}
}
EventFormForm.dart
class EventFormForm extends StatefulWidget {
// Some Code
// Some Const
#override
EventFormFormState createState() => EventFormFormState();
}
class EventFormFormState extends State<EventFormForm> {
//
//
// Some Code
//
//
#override
Widget build(BuildContext context) {
return Form(
//
// Some Code
//
);
}
saveForm() {
//
// Some Code
//
}
}
Tag #chunhunghan
You can copy paste run each files below
Step 1: Use final keyForm = GlobalKey<EventFormFormState>();
Step 2: Pass keyForm to EventFormForm(key: keyForm)
Step 3: In IconButton call keyForm.currentState.saveForm();
IconButton(
icon: Icon(Icons.save),
onPressed: () {
keyForm.currentState.saveForm();
})
working demo
full code
main.dart
import 'package:flutter/material.dart';
import 'event_form.dart';
import 'event_form_form.dart';
void main() => runApp(MyApp());
final keyForm = GlobalKey<EventFormFormState>();
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: EventForm(),
);
}
}
event_form.dart
import 'package:flutter/material.dart';
import 'event_form_appbar.dart';
import 'event_form_body.dart';
class EventForm extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(appBar: EventFormAppBar(), body: EventFormBody());
}
}
event_form_appbar.dart
import 'package:flutter/material.dart';
import 'main.dart';
class EventFormAppBar extends PreferredSize {
#override
Widget build(BuildContext context) {
return AppBar(actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {
keyForm.currentState.saveForm();
})
]);
}
#override
get preferredSize => Size.fromHeight(50);
}
event_form_body.dart
import 'package:flutter/material.dart';
import 'main.dart';
import 'event_form_form.dart';
class EventFormBody extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: EventFormForm(key: keyForm),
),
);
}
}
event_form_form.dart
import 'package:flutter/material.dart';
class EventFormForm extends StatefulWidget {
EventFormForm({Key key}) : super(key: key);
#override
EventFormFormState createState() {
return EventFormFormState();
}
}
class EventFormFormState extends State<EventFormForm> {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: RaisedButton(
onPressed: () {
saveForm();
},
child: Text('Submit'),
),
),
],
),
);
}
void saveForm() {
print("execute save Form");
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('Processing Data')));
}
}
}
Flutter camera app renders very slowly when using websockets in image streams. How can I improve my app performance? what is the best way to overcome this? On emulator it works just fine but on real device there is lot of delay and stuttering. Can we use async for camera app? If yes, how can I use it with this code?
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:web_socket_channel/io.dart';
import 'dart:convert';
import 'package:archive/archive.dart';
List<CameraDescription> cameras;
Future<void> main() async {
cameras = await availableCameras();
runApp(App());
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: CameraApp(),
);
}
}
class CameraApp extends StatefulWidget {
#override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
CameraController controller;
IOWebSocketChannel channel = IOWebSocketChannel.connect('ws://192.168.0.6:8000/');
#override
void initState() {
super.initState();
controller = CameraController(cameras[1], ResolutionPreset.low);
controller.initialize().then((_) async{
await controller.startImageStream((onAvailable) {
sd(onAvailable);
});
if (!mounted) {
return;
}
setState(() {});
});
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
#override
void sd(onAvailable) {
var framesY = onAvailable.planes[0].bytes;
List<int> gzipBytes = new GZipEncoder().encode(framesY);
String compressedString = base64Encode(gzipBytes);
channel.sink.add(compressedString);
}
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
return new Scaffold(
body: new Container(
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),
);
}
}
I wanted to know if there is any way to show a real time clock in dart?
Date and time (e.g 11/14/2018 19:34) and the time will continue to run.
Time can be taken from the device itself.
The below uses the intl plugin to format the time into MM/dd/yyyy hh:mm:ss. Make sure to update your pubspec.yaml.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Time Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Time Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _timeString;
#override
void initState() {
_timeString = _formatDateTime(DateTime.now());
Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text(_timeString),
),
);
}
void _getTime() {
final DateTime now = DateTime.now();
final String formattedDateTime = _formatDateTime(now);
setState(() {
_timeString = formattedDateTime;
});
}
String _formatDateTime(DateTime dateTime) {
return DateFormat('MM/dd/yyyy hh:mm:ss').format(dateTime);
}
}
Simplest solution:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class ClockWidget extends StatelessWidget {
const ClockWidget({super.key});
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Stream.periodic(const Duration(seconds: 1)),
builder: (context, snapshot) {
return Text(DateFormat('MM/dd/yyyy hh:mm:ss').format(DateTime.now()));
},
);
}
}
Put it anywhere you like.
This is the same code which Albert had given, but in case you don't want to use the intl package, you can make these changes to this code:
import 'package:flutter/material.dart';
import 'dart:async';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.red),
home: FlutterTimeDemo(),
);
}
}
class FlutterTimeDemo extends StatefulWidget{
#override
_FlutterTimeDemoState createState()=> _FlutterTimeDemoState();
}
class _FlutterTimeDemoState extends State<FlutterTimeDemo>
{
String _timeString;
#override
void initState(){
_timeString = "${DateTime.now().hour} : ${DateTime.now().minute} :${DateTime.now().second}";
Timer.periodic(Duration(seconds:1), (Timer t)=>_getCurrentTime());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Fluter Test'),),
body:Center(
child: Text(_timeString, style: TextStyle(fontSize: 30),),
),
);
}
void _getCurrentTime() {
setState(() {
_timeString = "${DateTime.now().hour} : ${DateTime.now().minute} :${DateTime.now().second}";
});
}
}