Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
[image_picker] Migrate to null-safety (#3524)
Browse files Browse the repository at this point in the history
Migrate image_picker to null-safety
  • Loading branch information
Sameerkash authored Feb 8, 2021
1 parent 0cec317 commit 3d70464
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 498 deletions.
6 changes: 6 additions & 0 deletions packages/image_picker/image_picker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.7.0-nullsafety
* Migrate to nullsafety
* Breaking Changes:
* Removed the deprecated methods: `ImagePicker.pickImage`, `ImagePicker.pickVideo`,
`ImagePicker.retrieveLostData`

## 0.6.7+22

* iOS: update XCUITests to separate each test session.
Expand Down
97 changes: 50 additions & 47 deletions packages/image_picker/image_picker/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,60 +29,63 @@ class MyApp extends StatelessWidget {
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
MyHomePage({Key? key, this.title}) : super(key: key);

final String title;
final String? title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
PickedFile _imageFile;
PickedFile? _imageFile;
dynamic _pickImageError;
bool isVideo = false;
VideoPlayerController _controller;
VideoPlayerController _toBeDisposed;
String _retrieveDataError;
VideoPlayerController? _controller;
VideoPlayerController? _toBeDisposed;
String? _retrieveDataError;

final ImagePicker _picker = ImagePicker();
final TextEditingController maxWidthController = TextEditingController();
final TextEditingController maxHeightController = TextEditingController();
final TextEditingController qualityController = TextEditingController();

Future<void> _playVideo(PickedFile file) async {
Future<void> _playVideo(PickedFile? file) async {
if (file != null && mounted) {
await _disposeVideoController();
late VideoPlayerController controller;
if (kIsWeb) {
_controller = VideoPlayerController.network(file.path);
// In web, most browsers won't honor a programmatic call to .play
// if the video has a sound track (and is not muted).
// Mute the video so it auto-plays in web!
// This is not needed if the call to .play is the result of user
// interaction (clicking on a "play" button, for example).
await _controller.setVolume(0.0);
controller = VideoPlayerController.network(file.path);
} else {
_controller = VideoPlayerController.file(File(file.path));
await _controller.setVolume(1.0);
controller = VideoPlayerController.file(File(file.path));
}
await _controller.initialize();
await _controller.setLooping(true);
await _controller.play();
_controller = controller;
// In web, most browsers won't honor a programmatic call to .play
// if the video has a sound track (and is not muted).
// Mute the video so it auto-plays in web!
// This is not needed if the call to .play is the result of user
// interaction (clicking on a "play" button, for example).
final double volume = kIsWeb ? 0.0 : 1.0;
await controller.setVolume(volume);
await controller.initialize();
await controller.setLooping(true);
await controller.play();
setState(() {});
}
}

void _onImageButtonPressed(ImageSource source, {BuildContext context}) async {
void _onImageButtonPressed(ImageSource source,
{BuildContext? context}) async {
if (_controller != null) {
await _controller.setVolume(0.0);
await _controller!.setVolume(0.0);
}
if (isVideo) {
final PickedFile file = await _picker.getVideo(
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 {
await _displayPickImageDialog(context!,
(double? maxWidth, double? maxHeight, int? quality) async {
try {
final pickedFile = await _picker.getImage(
source: source,
Expand All @@ -105,8 +108,8 @@ class _MyHomePageState extends State<MyHomePage> {
@override
void deactivate() {
if (_controller != null) {
_controller.setVolume(0.0);
_controller.pause();
_controller!.setVolume(0.0);
_controller!.pause();
}
super.deactivate();
}
Expand All @@ -122,14 +125,14 @@ class _MyHomePageState extends State<MyHomePage> {

Future<void> _disposeVideoController() async {
if (_toBeDisposed != null) {
await _toBeDisposed.dispose();
await _toBeDisposed!.dispose();
}
_toBeDisposed = _controller;
_controller = null;
}

Widget _previewVideo() {
final Text retrieveError = _getRetrieveErrorWidget();
final Text? retrieveError = _getRetrieveErrorWidget();
if (retrieveError != null) {
return retrieveError;
}
Expand All @@ -146,18 +149,18 @@ class _MyHomePageState extends State<MyHomePage> {
}

Widget _previewImage() {
final Text retrieveError = _getRetrieveErrorWidget();
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);
return Image.network(_imageFile!.path);
} else {
return Semantics(
child: Image.file(File(_imageFile.path)),
child: Image.file(File(_imageFile!.path)),
label: 'image_picker_example_picked_image');
}
} else if (_pickImageError != null) {
Expand Down Expand Up @@ -189,15 +192,15 @@ class _MyHomePageState extends State<MyHomePage> {
});
}
} else {
_retrieveDataError = response.exception.code;
_retrieveDataError = response.exception!.code;
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
title: Text(widget.title!),
),
body: Center(
child: !kIsWeb && defaultTargetPlatform == TargetPlatform.android
Expand Down Expand Up @@ -288,9 +291,9 @@ class _MyHomePageState extends State<MyHomePage> {
);
}

Text _getRetrieveErrorWidget() {
Text? _getRetrieveErrorWidget() {
if (_retrieveDataError != null) {
final Text result = Text(_retrieveDataError);
final Text result = Text(_retrieveDataError!);
_retrieveDataError = null;
return result;
}
Expand Down Expand Up @@ -336,13 +339,13 @@ class _MyHomePageState extends State<MyHomePage> {
TextButton(
child: const Text('PICK'),
onPressed: () {
double width = maxWidthController.text.isNotEmpty
double? width = maxWidthController.text.isNotEmpty
? double.parse(maxWidthController.text)
: null;
double height = maxHeightController.text.isNotEmpty
double? height = maxHeightController.text.isNotEmpty
? double.parse(maxHeightController.text)
: null;
int quality = qualityController.text.isNotEmpty
int? quality = qualityController.text.isNotEmpty
? int.parse(qualityController.text)
: null;
onPick(width, height, quality);
Expand All @@ -355,40 +358,40 @@ class _MyHomePageState extends State<MyHomePage> {
}

typedef void OnPickImageCallback(
double maxWidth, double maxHeight, int quality);
double? maxWidth, double? maxHeight, int? quality);

class AspectRatioVideo extends StatefulWidget {
AspectRatioVideo(this.controller);

final VideoPlayerController controller;
final VideoPlayerController? controller;

@override
AspectRatioVideoState createState() => AspectRatioVideoState();
}

class AspectRatioVideoState extends State<AspectRatioVideo> {
VideoPlayerController get controller => widget.controller;
VideoPlayerController? get controller => widget.controller;
bool initialized = false;

void _onVideoControllerUpdate() {
if (!mounted) {
return;
}
if (initialized != controller.value.initialized) {
initialized = controller.value.initialized;
if (initialized != controller!.value.isInitialized) {
initialized = controller!.value.isInitialized;
setState(() {});
}
}

@override
void initState() {
super.initState();
controller.addListener(_onVideoControllerUpdate);
controller!.addListener(_onVideoControllerUpdate);
}

@override
void dispose() {
controller.removeListener(_onVideoControllerUpdate);
controller!.removeListener(_onVideoControllerUpdate);
super.dispose();
}

Expand All @@ -397,8 +400,8 @@ class AspectRatioVideoState extends State<AspectRatioVideo> {
if (initialized) {
return Center(
child: AspectRatio(
aspectRatio: controller.value?.aspectRatio,
child: VideoPlayer(controller),
aspectRatio: controller!.value.aspectRatio,
child: VideoPlayer(controller!),
),
);
} else {
Expand Down
9 changes: 4 additions & 5 deletions packages/image_picker/image_picker/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@ description: Demonstrates how to use the image_picker plugin.
author: Flutter Team <flutter-dev@googlegroups.com>

dependencies:
video_player: ^0.10.3
video_player: ^2.0.0-nullsafety.7
flutter:
sdk: flutter
flutter_plugin_android_lifecycle: ^1.0.2
flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2
image_picker:
path: ../
image_picker_for_web: ^0.1.0

dev_dependencies:
flutter_driver:
sdk: flutter
integration_test:
path: ../../../integration_test
pedantic: ^1.8.0
pedantic: ^1.10.0

flutter:
uses-material-design: true

environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"
flutter: ">=1.10.0 <2.0.0"
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @dart=2.9

import 'package:integration_test/integration_test.dart';

void main() {
Expand Down
Loading

0 comments on commit 3d70464

Please sign in to comment.