| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- // Copyright 2019 The Flutter Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- // ignore_for_file: public_member_api_docs
- import 'dart:async';
- import 'dart:io';
- import 'package:flutter/foundation.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/src/widgets/basic.dart';
- import 'package:flutter/src/widgets/container.dart';
- import 'package:image_picker/image_picker.dart';
- import 'package:video_player/video_player.dart';
- void main() {
- runApp(MyApp());
- }
- class MyApp extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- title: 'Image Picker Demo',
- home: MyHomePage(title: 'Image Picker Example'),
- );
- }
- }
- class MyHomePage extends StatefulWidget {
- MyHomePage({Key key, this.title}) : super(key: key);
- final String title;
- @override
- _MyHomePageState createState() => _MyHomePageState();
- }
- class _MyHomePageState extends State<MyHomePage> {
- PickedFile _imageFile;
- dynamic _pickImageError;
- bool isVideo = false;
- VideoPlayerController _controller;
- String _retrieveDataError;
- final ImagePicker _picker = ImagePicker();
- final TextEditingController maxWidthController = TextEditingController();
- final TextEditingController maxHeightController = TextEditingController();
- final TextEditingController qualityController = TextEditingController();
- Future<void> _playVideo(PickedFile file) async {
- if (file != null && mounted) {
- await _disposeVideoController();
- if (kIsWeb) {
- _controller = VideoPlayerController.network(file.path);
- } else {
- _controller = VideoPlayerController.file(File(file.path));
- }
- await _controller.setVolume(1.0);
- await _controller.initialize();
- await _controller.setLooping(true);
- await _controller.play();
- setState(() {});
- }
- }
- void _onImageButtonPressed(ImageSource source, {BuildContext context}) async {
- if (_controller != null) {
- await _controller.setVolume(0.0);
- }
- if (isVideo) {
- final PickedFile file = await _picker.getVideo(
- source: source, maxDuration: const Duration(seconds: 10));
- await _playVideo(file);
- } else {
- await _displayPickImageDialog(context,
- (double maxWidth, double maxHeight, int quality) async {
- try {
- final pickedFile = await _picker.getImage(
- source: source,
- maxWidth: maxWidth,
- maxHeight: maxHeight,
- imageQuality: quality,
- );
- setState(() {
- _imageFile = pickedFile;
- });
- } catch (e) {
- setState(() {
- _pickImageError = e;
- });
- }
- });
- }
- }
- @override
- void deactivate() {
- if (_controller != null) {
- _controller.setVolume(0.0);
- _controller.pause();
- }
- super.deactivate();
- }
- @override
- void dispose() {
- _disposeVideoController();
- maxWidthController.dispose();
- maxHeightController.dispose();
- qualityController.dispose();
- super.dispose();
- }
- Future<void> _disposeVideoController() async {
- if (_controller != null) {
- await _controller.dispose();
- _controller = null;
- }
- }
- Widget _previewVideo() {
- final Text retrieveError = _getRetrieveErrorWidget();
- if (retrieveError != null) {
- return retrieveError;
- }
- if (_controller == null) {
- return const Text(
- 'You have not yet picked a video',
- textAlign: TextAlign.center,
- );
- }
- return Padding(
- padding: const EdgeInsets.all(10.0),
- child: AspectRatioVideo(_controller),
- );
- }
- Widget _previewImage() {
- final Text retrieveError = _getRetrieveErrorWidget();
- if (retrieveError != null) {
- return retrieveError;
- }
- if (_imageFile != null) {
- if (kIsWeb) {
- // Why network?
- // See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform
- return Image.network(_imageFile.path);
- } else {
- return Image.file(File(_imageFile.path));
- }
- } else if (_pickImageError != null) {
- return Text(
- 'Pick image error: $_pickImageError',
- textAlign: TextAlign.center,
- );
- } else {
- return const Text(
- 'You have not yet picked an image.',
- textAlign: TextAlign.center,
- );
- }
- }
- Future<void> retrieveLostData() async {
- final LostData response = await _picker.getLostData();
- if (response.isEmpty) {
- return;
- }
- if (response.file != null) {
- if (response.type == RetrieveType.video) {
- isVideo = true;
- await _playVideo(response.file);
- } else {
- isVideo = false;
- setState(() {
- _imageFile = response.file;
- });
- }
- } else {
- _retrieveDataError = response.exception.code;
- }
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text(widget.title),
- ),
- body: Center(
- child: !kIsWeb && defaultTargetPlatform == TargetPlatform.android
- ? FutureBuilder<void>(
- future: retrieveLostData(),
- builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
- switch (snapshot.connectionState) {
- case ConnectionState.none:
- case ConnectionState.waiting:
- return const Text(
- 'You have not yet picked an image.',
- textAlign: TextAlign.center,
- );
- case ConnectionState.done:
- return isVideo ? _previewVideo() : _previewImage();
- default:
- if (snapshot.hasError) {
- return Text(
- 'Pick image/video error: ${snapshot.error}}',
- textAlign: TextAlign.center,
- );
- } else {
- return const Text(
- 'You have not yet picked an image.',
- textAlign: TextAlign.center,
- );
- }
- }
- },
- )
- : (isVideo ? _previewVideo() : _previewImage()),
- ),
- floatingActionButton: Column(
- mainAxisAlignment: MainAxisAlignment.end,
- children: <Widget>[
- FloatingActionButton(
- onPressed: () {
- isVideo = false;
- _onImageButtonPressed(ImageSource.gallery, context: context);
- },
- heroTag: 'image0',
- tooltip: 'Pick Image from gallery',
- child: const Icon(Icons.photo_library),
- ),
- Padding(
- padding: const EdgeInsets.only(top: 16.0),
- child: FloatingActionButton(
- onPressed: () {
- isVideo = false;
- _onImageButtonPressed(ImageSource.camera, context: context);
- },
- heroTag: 'image1',
- tooltip: 'Take a Photo',
- child: const Icon(Icons.camera_alt),
- ),
- ),
- Padding(
- padding: const EdgeInsets.only(top: 16.0),
- child: FloatingActionButton(
- backgroundColor: Colors.red,
- onPressed: () {
- isVideo = true;
- _onImageButtonPressed(ImageSource.gallery);
- },
- heroTag: 'video0',
- tooltip: 'Pick Video from gallery',
- child: const Icon(Icons.video_library),
- ),
- ),
- Padding(
- padding: const EdgeInsets.only(top: 16.0),
- child: FloatingActionButton(
- backgroundColor: Colors.red,
- onPressed: () {
- isVideo = true;
- _onImageButtonPressed(ImageSource.camera);
- },
- heroTag: 'video1',
- tooltip: 'Take a Video',
- child: const Icon(Icons.videocam),
- ),
- ),
- ],
- ),
- );
- }
- Text _getRetrieveErrorWidget() {
- if (_retrieveDataError != null) {
- final Text result = Text(_retrieveDataError);
- _retrieveDataError = null;
- return result;
- }
- return null;
- }
- Future<void> _displayPickImageDialog(
- BuildContext context, OnPickImageCallback onPick) async {
- return showDialog(
- context: context,
- builder: (context) {
- return AlertDialog(
- title: Text('Add optional parameters'),
- content: Column(
- children: <Widget>[
- TextField(
- controller: maxWidthController,
- keyboardType: TextInputType.numberWithOptions(decimal: true),
- decoration:
- InputDecoration(hintText: "Enter maxWidth if desired"),
- ),
- TextField(
- controller: maxHeightController,
- keyboardType: TextInputType.numberWithOptions(decimal: true),
- decoration:
- InputDecoration(hintText: "Enter maxHeight if desired"),
- ),
- TextField(
- controller: qualityController,
- keyboardType: TextInputType.number,
- decoration:
- InputDecoration(hintText: "Enter quality if desired"),
- ),
- ],
- ),
- actions: <Widget>[
- FlatButton(
- child: const Text('CANCEL'),
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- FlatButton(
- child: const Text('PICK'),
- onPressed: () {
- double width = maxWidthController.text.isNotEmpty
- ? double.parse(maxWidthController.text)
- : null;
- double height = maxHeightController.text.isNotEmpty
- ? double.parse(maxHeightController.text)
- : null;
- int quality = qualityController.text.isNotEmpty
- ? int.parse(qualityController.text)
- : null;
- onPick(width, height, quality);
- Navigator.of(context).pop();
- }),
- ],
- );
- });
- }
- }
- typedef void OnPickImageCallback(
- double maxWidth, double maxHeight, int quality);
- class AspectRatioVideo extends StatefulWidget {
- AspectRatioVideo(this.controller);
- final VideoPlayerController controller;
- @override
- AspectRatioVideoState createState() => AspectRatioVideoState();
- }
- class AspectRatioVideoState extends State<AspectRatioVideo> {
- VideoPlayerController get controller => widget.controller;
- bool initialized = false;
- void _onVideoControllerUpdate() {
- if (!mounted) {
- return;
- }
- if (initialized != controller.value.initialized) {
- initialized = controller.value.initialized;
- setState(() {});
- }
- }
- @override
- void initState() {
- super.initState();
- controller.addListener(_onVideoControllerUpdate);
- }
- @override
- void dispose() {
- controller.removeListener(_onVideoControllerUpdate);
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- if (initialized) {
- return Center(
- child: AspectRatio(
- aspectRatio: controller.value?.aspectRatio,
- child: VideoPlayer(controller),
- ),
- );
- } else {
- return Container();
- }
- }
- }
|