Browse Source

widget media picker

master
daivph 5 years ago
parent
commit
811343a2d5
9 changed files with 168 additions and 70 deletions
  1. +2
    -0
      android/app/src/main/AndroidManifest.xml
  2. +1
    -1
      ios/Flutter/.last_build_id
  3. +6
    -0
      ios/Podfile.lock
  4. +2
    -15
      lib/presentation/custom_widgets/camera_helper.dart
  5. +1
    -0
      lib/presentation/custom_widgets/hoz_list_view.dart
  6. +80
    -54
      lib/presentation/custom_widgets/widget_media_picker.dart
  7. +73
    -0
      lib/presentation/custom_widgets/widget_show_video.dart
  8. +1
    -0
      lib/utils/const_common.dart
  9. +2
    -0
      lib/utils/const_string.dart

+ 2
- 0
android/app/src/main/AndroidManifest.xml View File

@@ -5,6 +5,8 @@
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<application

+ 1
- 1
ios/Flutter/.last_build_id View File

@@ -1 +1 @@
3c0c9b0c45d3aa2cb4c28b2c17dc1064
0d1f90510e22958a585802bb59f9c570

+ 6
- 0
ios/Podfile.lock View File

@@ -127,6 +127,8 @@ PODS:
- shared_preferences (0.0.1):
- Flutter
- SwiftProtobuf (1.12.0)
- thumbnails (0.0.1):
- Flutter
- video_player (0.0.1):
- Flutter

@@ -141,6 +143,7 @@ DEPENDENCIES:
- package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- thumbnails (from `.symlinks/plugins/thumbnails/ios`)
- video_player (from `.symlinks/plugins/video_player/ios`)

SPEC REPOS:
@@ -187,6 +190,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/path_provider/ios"
shared_preferences:
:path: ".symlinks/plugins/shared_preferences/ios"
thumbnails:
:path: ".symlinks/plugins/thumbnails/ios"
video_player:
:path: ".symlinks/plugins/video_player/ios"

@@ -221,6 +226,7 @@ SPEC CHECKSUMS:
SDWebImageFLPlugin: 6c2295fb1242d44467c6c87dc5db6b0a13228fd8
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699
thumbnails: bb4f4e9bb4b51c8ae4e6ad9a2fa81373f9b634ad
video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e

PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c

+ 2
- 15
lib/presentation/custom_widgets/camera_helper.dart View File

@@ -264,7 +264,7 @@ class _CameraHelperState extends State<CameraHelper>
});
if (filePath != null) {
print('Picture saved to $filePath');
Get.back(result: filePath);
Get.back(result: [filePath, false]);
}
}
});
@@ -284,24 +284,11 @@ class _CameraHelperState extends State<CameraHelper>
if (mounted) setState(() {});
{
print('Video recorded to: $videoPath');
_getImage(videoPath);
Get.back(result: [videoPath, true]);
}
});
}

_getImage(videoPathUrl) async {
var appDocDir = await getApplicationDocumentsDirectory();
final folderPath = appDocDir.path;
String thumb = await Thumbnails.getThumbnail(
thumbnailFolder: folderPath,
videoFile: videoPathUrl,
imageType:
ThumbFormat.PNG, //this image will store in created folderpath
quality: 30);
print("--thumb--" + thumb);
Get.back(result: thumb);
}

void onPauseButtonPressed() {
pauseVideoRecording().then((_) {
if (mounted) setState(() {});

+ 1
- 0
lib/presentation/custom_widgets/hoz_list_view.dart View File

@@ -32,6 +32,7 @@ class _WrapContentHozListViewState extends State<WrapContentHozListView> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
reverse: true,
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
child: Row(

+ 80
- 54
lib/presentation/custom_widgets/widget_media_picker.dart View File

@@ -2,17 +2,15 @@ import 'dart:io';

import 'package:farm_tpf/custom_model/Media.dart';
import 'package:farm_tpf/presentation/custom_widgets/camera_helper.dart';
import 'package:farm_tpf/presentation/custom_widgets/shimmer_image.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_show_video.dart';
import 'package:farm_tpf/utils/const_color.dart';
import 'package:farm_tpf/utils/const_common.dart';
import 'package:farm_tpf/utils/const_string.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get/route_manager.dart';
import 'package:path_provider/path_provider.dart';
import 'package:thumbnails/thumbnails.dart';
import 'package:video_player/video_player.dart';
import 'package:get/get.dart';

import 'bloc/media_helper_bloc.dart';
import 'hoz_list_view.dart';
@@ -83,7 +81,7 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
)),
),
SizedBox(
height: 4.0,
height: 8.0,
),
Container(
height: 150,
@@ -110,16 +108,27 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
if (value != null) {
print("ok");
print(value);
String filePath = value;
Media newMedia = Media()
..isVideo = false
..isServerFile = false
..pathFile = filePath;
currentItems.add(newMedia);
files.add(filePath);
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(files);
String filePath = value[0];
File f = File(filePath);
f.length().then((lengthFileInBytes) {
if (lengthFileInBytes > ConstCommon.kFileSize) {
Get.snackbar(label_file_to_large,
"Kích thước: $lengthFileInBytes bytes",
snackPosition: SnackPosition.BOTTOM);
} else {
bool isVideo = value[1];
Media newMedia = Media()
..isVideo = isVideo
..isServerFile = false
..pathFile = filePath;
currentItems.add(newMedia);
files.add(filePath);
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(files);
}
print("Kích thước: $lengthFileInBytes bytes");
});
}
});
}),
@@ -132,15 +141,23 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {

if (result != null) {
String filePath = result.files.single.path;
Media newMedia = Media()
..isVideo = false
..isServerFile = false
..pathFile = filePath;
currentItems.add(newMedia);
files.add(filePath);
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(files);
var lengthFileInBytes = result.files.single.size * 1000;
if (lengthFileInBytes > ConstCommon.kFileSize) {
Get.snackbar(label_file_to_large,
"Kích thước: $lengthFileInBytes bytes",
snackPosition: SnackPosition.BOTTOM);
} else {
Media newMedia = Media()
..isVideo = false
..isServerFile = false
..pathFile = filePath;
currentItems.add(newMedia);
files.add(filePath);
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(files);
}
print("file size: $lengthFileInBytes");
}
}),
CupertinoDialogAction(
@@ -151,25 +168,24 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
await FilePicker.platform.pickFiles(type: FileType.video);

if (result != null) {
//Get thumb video
var appDocDir = await getApplicationDocumentsDirectory();
final folderPath = appDocDir.path;
String filePath = await Thumbnails.getThumbnail(
thumbnailFolder: folderPath,
videoFile: result.files.single.path,
imageType: ThumbFormat
.PNG, //this image will store in created folderpath
quality: 30);

Media newMedia = Media()
..isVideo = false
..isServerFile = false
..pathFile = filePath;
currentItems.add(newMedia);
files.add(filePath);
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(files);
String filePath = result.files.single.path;
var lengthFileInBytes = result.files.single.size * 1000;
if (lengthFileInBytes > ConstCommon.kFileSize) {
Get.snackbar(label_file_to_large,
"Kích thước: $lengthFileInBytes bytes",
snackPosition: SnackPosition.BOTTOM);
} else {
Media newMedia = Media()
..isVideo = true
..isServerFile = false
..pathFile = filePath;
currentItems.add(newMedia);
files.add(filePath);
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(files);
}
print("file size: $lengthFileInBytes");
}
}),
CupertinoDialogAction(
@@ -201,7 +217,7 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
});
},
separatorBuilder: (context, index) {
return SizedBox(width: 14);
return SizedBox(width: 4);
},
list: state.items,
);
@@ -222,9 +238,6 @@ class _WidgetItemMedia extends StatelessWidget {
@override
Widget build(BuildContext context) {
_context = context;
VideoPlayerController _controller =
VideoPlayerController.file(File(item.pathFile));
_controller.play();
return GestureDetector(
onTap: () {
print("Show preview image or video");
@@ -234,17 +247,30 @@ class _WidgetItemMedia extends StatelessWidget {
overflow: Overflow.visible,
children: <Widget>[
Positioned(
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.file(File(item.pathFile), width: 100, height: 100),
)),
child: item.isVideo
? VideoWidget(
pathFile: item.pathFile,
play: false,
)
: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius:
BorderRadius.all(Radius.circular(8.0))),
child: Image.file(File(item.pathFile),
width: 100, height: 100),
)),
Positioned(
top: -5,
right: -5,
top: -14,
right: -14,
child: IconButton(
icon: Icon(
Icons.cancel,
color: Colors.redAccent,
size: 24,
),
onPressed: () {
print("On tap delete media");

+ 73
- 0
lib/presentation/custom_widgets/widget_show_video.dart View File

@@ -0,0 +1,73 @@
import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

class VideoWidget extends StatefulWidget {
final bool play;
final String pathFile;

const VideoWidget({Key key, @required this.pathFile, @required this.play})
: super(key: key);

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

class _VideoWidgetState extends State<VideoWidget> {
VideoPlayerController videoPlayerController;
Future<void> _initializeVideoPlayerFuture;

@override
void initState() {
super.initState();
videoPlayerController = VideoPlayerController.file(File(widget.pathFile));
_initializeVideoPlayerFuture = videoPlayerController.initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
videoPlayerController.play();
videoPlayerController.setVolume(0.0);
Timer.periodic(Duration(seconds: 1), (_) {
videoPlayerController.pause();
});
setState(() {});
});
}

@override
void dispose() {
videoPlayerController.dispose();
print("dispose video item");
super.dispose();
}

@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return new Container(
child: Container(
key: new PageStorageKey(widget.pathFile),
child: Container(
padding: EdgeInsets.all(1),
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(8.0))),
child: VideoPlayer(videoPlayerController),
),
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
);
}
}

+ 1
- 0
lib/utils/const_common.dart View File

@@ -1,5 +1,6 @@
class ConstCommon {
static int kExpiredTime = 12 * 60 * 60 * 1000; //24h
static int kFileSize = 1000000; //1M = 1000.000 bytes
static const String baseUrl = "http://tpf.aztrace.vn";

static const String supplyTypeSeed = "GIONG";

+ 2
- 0
lib/utils/const_string.dart View File

@@ -33,6 +33,8 @@ const String label_error_get_data = "Lỗi tải dữ liệu";
const String label_update_success = "Cập nhật thành công";
const String label_add_success = "Thêm thành công";

const String label_file_to_large = "Kích thước hình/video quá lớn";

//Exception
const String exception_common = "Đã có lỗi xảy ra";
const String exception_dio_cancle = "Truy vấn đến máy chủ bị huỷ";

Loading…
Cancel
Save