Reason Pun

增加视频录制和播放页面功能,增加清栈和提示

......@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
import 'package:one_poem/res/constant.dart';
import 'package:one_poem/routers/fluro_navigator.dart';
import 'package:one_poem/extension/int_extension.dart';
/// 创建人: Created by zhaolong
/// 创建时间:Created by on 2020/12/12.
///
......@@ -11,7 +13,6 @@ import 'package:one_poem/routers/fluro_navigator.dart';
/// 可关注博客:https://blog.csdn.net/zl18603543572
///
/// 代码清单
///代码清单
class ProtocolModel {
late TapGestureRecognizer _registerProtocolRecognizer;
late TapGestureRecognizer _privacyProtocolRecognizer;
......@@ -23,7 +24,6 @@ class ProtocolModel {
//隐私协议的手势
_privacyProtocolRecognizer = TapGestureRecognizer();
//苹果风格弹框
bool isShow = await showDialog(
//上下文对象
context: context,
......@@ -40,12 +40,12 @@ class ProtocolModel {
return Future.value(isShow);
}
AlertDialog showAlertDialog(BuildContext context) {
AlertDialog showAlertDialog(BuildContext context) {
return AlertDialog(
title: const Text("温馨提示"),
content: Container(
height: 260,
padding: const EdgeInsets.all(1),
height: 260.px,
padding: EdgeInsets.all(1.px),
//可滑动布局
child: SingleChildScrollView(
child: buildContent(context),
......@@ -71,7 +71,6 @@ class ProtocolModel {
//协议说明文案
String userPrivateProtocol =
"我们一向尊重并会严格保护用户在使用本产品时的合法权益(包括用户隐私、用户数据等)不受到任何侵犯。本协议(包括本文最后部分的隐私政策)是用户(包括通过各种合法途径获取到本产品的自然人、法人或其他组织机构,以下简称“用户”或“您”)与我们之间针对本产品相关事项最终的、完整的且排他的协议,并取代、合并之前的当事人之间关于上述事项的讨论和协议。本协议将对用户使用本产品的行为产生法律约束力,您已承诺和保证有权利和能力订立本协议。用户开始使用本产品将视为已经接受本协议,请认真阅读并理解本协议中各种条款,包括免除和限制我们的免责条款和对用户的权利限制(未成年人审阅时应由法定监护人陪同),如果您不能接受本协议中的全部条款,请勿开始使用本产品";
buildContent(BuildContext context) {
return RichText(
text: TextSpan(
......
import 'package:flutter/material.dart';
import 'package:one_poem/res/resources.dart';
import 'package:one_poem/routers/fluro_navigator.dart';
import 'package:one_poem/routers/routers.dart';
import 'package:one_poem/util/toast_utils.dart';
import 'package:one_poem/widgets/my_app_bar.dart';
import 'package:one_poem/extension/int_extension.dart';
class PoemPublish extends StatefulWidget {
const PoemPublish({Key? key, required this.data}) : super(key: key);
......@@ -24,124 +28,158 @@ class _PoemPublishState extends State<PoemPublish> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppBar(
homeMenuHeader: Container(
alignment: Alignment.center,
width: double.infinity,
child: const Text(
"发布临境",
style: TextStyle(
color: Colors.white,
return WillPopScope(
onWillPop: _isExit,
child: Scaffold(
appBar: MyAppBar(
homeMenuHeader: Container(
alignment: Alignment.center,
width: double.infinity,
child: const Text(
"发布临境",
style: TextStyle(
color: Colors.white,
),
),
),
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(
10.0,
),
child: ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 200,
maxWidth: double.infinity,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(
10.0,
),
child: TextField(
maxLines: 10,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
hintText: '读此一言,仿佛身临其境',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide.none),
filled: true,
fillColor: Colors.grey.shade100,
),
),
),
),
Container(
padding: const EdgeInsets.all(10.0),
alignment: Alignment.centerLeft,
width: double.infinity,
height: 36.0,
child: Wrap(
children: const [
Icon(
Icons.room_outlined,
size: 15,
child: ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 200,
maxWidth: double.infinity,
),
Text(
"我在此地",
style: TextStyle(color: Colors.black45),
child: TextField(
maxLines: 10,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
hintText: '读此一言,仿佛身临其境',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide.none),
filled: true,
fillColor: Colors.grey.shade100,
),
),
],
),
),
),
Container(
padding: const EdgeInsets.all(10.0),
alignment: Alignment.centerLeft,
width: double.infinity,
height: 36.0,
child: Wrap(
children: const [
Icon(
Icons.room_outlined,
size: 15,
),
Text(
"所用口音",
style: TextStyle(color: Colors.black45),
),
Gaps.hGap10,
Text(
"普通话",
style: TextStyle(color: Colors.black45),
),
],
Container(
padding: EdgeInsets.all(10.px),
alignment: Alignment.centerLeft,
width: double.infinity,
height: 36.px,
child: Wrap(
children: [
Icon(
Icons.room_outlined,
size: 15.px,
),
Gaps.hGap5,
const Text(
"我在此地",
style: TextStyle(color: Colors.black45),
),
],
),
),
),
Gaps.vGap24,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 36.0,
alignment: Alignment.center,
width: double.infinity,
child: const Text(
"发布临境,让更多人身临其境",
style: TextStyle(fontSize: 12.0),
Container(
padding: EdgeInsets.all(10.px),
alignment: Alignment.centerLeft,
width: double.infinity,
height: 36.px,
child: Wrap(
children: [
Icon(
Icons.record_voice_over_outlined,
size: 15.px,
),
),
Container(
height: 48.0,
alignment: Alignment.center,
width: double.infinity,
child: TextButton(
style: ButtonStyle(
side: MaterialStateProperty.all(
const BorderSide(color: Colors.black54, width: 1),
),
Gaps.hGap5,
const Text(
"所用口音",
style: TextStyle(color: Colors.black45),
),
Gaps.hGap10,
const Text(
"普通话",
style: TextStyle(color: Colors.black45),
),
],
),
),
const Spacer(),
Expanded(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"发布临境,让更多人身临其境",
style: TextStyle(fontSize: 14.px),
),
onPressed: () {
Toast.show("先不发布了吧。。。。");
},
child: const Text(
"发布",
style: TextStyle(color: Colors.black54, fontSize: 15.0),
Gaps.vGap10,
TextButton(
style: ButtonStyle(
side: MaterialStateProperty.all(
BorderSide(
color: Colors.black54,
width: 1.px,
),
),
),
onPressed: () {
Toast.show("先不发布了吧。。。。");
},
child: Text(
"发布",
style:
TextStyle(color: Colors.black54, fontSize: 15.px),
),
),
),
],
),
],
),
),
),
],
],
),
),
);
}
Future<bool> _isExit() async {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("温馨提示"),
content: Container(
padding: EdgeInsets.all(1.px),
//可滑动布局
child: const Text("确认放弃此次作品吗?"),
),
actions: [
TextButton(
child: const Text("再想想"),
onPressed: () {
Navigator.of(context).pop(true);
},
),
TextButton(
child: const Text("残忍放弃"),
onPressed: () {
NavigatorUtils.push(context, Routes.home, clearStack: true);
},
),
],
);
},
);
return Future.value(false);
}
}
......
......@@ -4,6 +4,8 @@ import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:one_poem/res/resources.dart';
import 'package:one_poem/routers/fluro_navigator.dart';
import 'package:one_poem/util/toast_utils.dart';
import 'package:one_poem/widgets/my_app_bar.dart';
import 'package:path_provider/path_provider.dart';
......@@ -11,6 +13,8 @@ import 'package:pausable_timer/pausable_timer.dart';
import 'package:video_player/video_player.dart';
import 'package:one_poem/extension/int_extension.dart';
import '../poem_router.dart';
class PoemRecordVideoPage extends StatefulWidget {
const PoemRecordVideoPage({Key? key}) : super(key: key);
......@@ -44,7 +48,7 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
///记录当前的时间
int currentTimer = 0;
int duration = 60 * 1000;
int duration = 10 * 1000; //TODO 60 * 1000;
@override
void initState() {
......@@ -244,19 +248,19 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
try {
XFile? rawVideo = await stopVideoRecording();
File videoFile = File(rawVideo!.path);
int currentUnix = DateTime.now().millisecondsSinceEpoch;
final directory = await getApplicationDocumentsDirectory();
String fileFormat = videoFile.path.split('.').last;
_videoFile = await videoFile.copy(
'${directory.path}/$currentUnix.$fileFormat',
);
// TODO why pause!直接使用cancel()会出现问题,暂时这么解决
_timer.pause();
NavigatorUtils.push(
context,
'${PoemRouter.poemVideoPlayer}?url=100',
);
} catch (e) {
// print(e);
}
......@@ -276,13 +280,49 @@ class _PoemRecordVideoPageState extends State<PoemRecordVideoPage>
controller!.buildPreview(),
Padding(
padding: EdgeInsets.fromLTRB(10.px, 30.px, 10.px, 10.px),
child: Text(
"清晨入古寺,\n初日照高林。\n曲径通幽处,\n禅房花木深。\n山光悦鸟性,\n潭影空人心。\n万籁此都寂,\n但余钟磬音。\n",
style: TextStyle(
color: Colors.white,
fontFamily: "ZCOOLXiaoWei",
fontSize: 20.px,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"题破山寺后禅院",
style: TextStyle(
color: Colors.white,
fontSize: 28.px,
),
),
Gaps.vGap10,
Text(
"常建",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
),
),
Gaps.vGap5,
Text(
"清晨入古寺,\n初日照高林。\n曲径通幽处,\n禅房花木深。\n山光悦鸟性,\n潭影空人心。\n万籁此都寂,\n但余钟磬音。\n",
style: TextStyle(
color: Colors.white,
fontFamily: "ZCOOLXiaoWei",
fontSize: 25.px,
),
),
Gaps.vGap5,
Text(
"临者:老魔取西经",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
),
),
Text(
"2022年01月25日 辰时三刻",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
),
),
],
),
),
Padding(
......
import 'package:fijkplayer/fijkplayer.dart';
import 'package:flutter/material.dart';
import 'package:one_poem/res/resources.dart';
import 'package:one_poem/routers/fluro_navigator.dart';
import 'package:one_poem/widgets/my_app_bar.dart';
import 'package:one_poem/extension/int_extension.dart';
import '../poem_router.dart';
class PoemVideoPlayer extends StatefulWidget {
final String url;
......@@ -26,7 +31,11 @@ class _PoemVideoPlayerState extends State<PoemVideoPlayer> {
super.initState();
// player.setDataSource(widget.url, autoPlay: true);
//TODO 替换真实URL
player.setDataSource("asset:///assets/data/video_01.mp4", autoPlay: true);
player.setDataSource(
"asset:///assets/data/video_01.mp4",
autoPlay: true,
);
player.setLoop(0);
}
@override
......@@ -37,22 +46,94 @@ class _PoemVideoPlayerState extends State<PoemVideoPlayer> {
alignment: Alignment.center,
child: Text(
widget.title ?? "视频播放",
style: const TextStyle(color: Colors.white),
style: const TextStyle(
color: Colors.white,
),
),
),
),
body: Container(
alignment: Alignment.center,
child: FijkView(
height: MediaQuery.of(context).size.height,
player: player,
),
body: Stack(
children: [
FijkView(
height: MediaQuery.of(context).size.height,
player: player,
fit: FijkFit.fill,
),
Padding(
padding: EdgeInsets.fromLTRB(10.px, 30.px, 10.px, 10.px),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"题破山寺后禅院",
style: TextStyle(
color: Colors.white,
fontSize: 28.px,
),
),
Gaps.vGap10,
Text(
"常建",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
),
),
Gaps.vGap5,
Text(
"清晨入古寺,\n初日照高林。\n曲径通幽处,\n禅房花木深。\n山光悦鸟性,\n潭影空人心。\n万籁此都寂,\n但余钟磬音。\n",
style: TextStyle(
color: Colors.white,
fontFamily: "ZCOOLXiaoWei",
fontSize: 25.px,
),
),
Gaps.vGap5,
Text(
"临者:老魔取西经",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
),
),
Text(
"2022年01月25日 辰时三刻",
style: TextStyle(
color: Colors.white,
fontSize: 15.px,
),
),
],
),
),
Positioned(
bottom: 10.px,
right: 20.px,
child: ElevatedButton(
onPressed: () {
NavigatorUtils.push(
context,
'${PoemRouter.poemPublish}?data=100',
clearStack: true
);
},
child: Text(
"下一步",
style: TextStyle(fontSize: 15.px),
),
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.black54,
),
),
),
],
));
}
@override
void dispose() {
super.dispose();
player.release();
super.dispose();
}
}
......