Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
laki_icu_app
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张宏
laki_icu_app
Commits
9895a233
Commit
9895a233
authored
Jun 20, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
加入全屏页面
parent
f7ca117d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
93 additions
and
137 deletions
+93
-137
camera_controls.dart
lib/views/home/index/widgets/camera_controls.dart
+0
-137
monitoring_screen.dart
lib/views/home/index/widgets/monitoring_screen.dart
+0
-0
webrtc_fullscreen_page.dart
lib/views/home/index/widgets/webrtc_fullscreen_page.dart
+59
-0
webrtc_video_widget.dart
lib/views/home/index/widgets/webrtc_video_widget.dart
+34
-0
No files found.
lib/views/home/index/widgets/camera_controls.dart
deleted
100644 → 0
View file @
f7ca117d
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
/// 摄像头控制按钮组件
///
/// 职责:
/// - 提供拍照、录像、刷新三个操作按钮
/// - 录像按钮支持录制中/停止录制两种状态切换
/// - 摄像头未就绪时按钮置灰不可操作
///
/// 涉及页面:首页监护舱页面 - 监控画面底部控制栏
class
CameraControls
extends
StatelessWidget
{
/// 是否正在录像
final
bool
isRecording
;
/// 摄像头是否已就绪(已打开)
final
bool
cameraReady
;
/// 是否已全屏
final
bool
isFullscreen
;
/// 拍照回调
final
VoidCallback
?
onTakePhoto
;
/// 切换录像状态回调(开始/停止)
final
VoidCallback
?
onToggleRecord
;
/// 刷新回调
final
VoidCallback
?
onRefresh
;
/// 切换全屏回调
final
VoidCallback
?
onToggleFullscreen
;
const
CameraControls
({
super
.
key
,
this
.
isRecording
=
false
,
this
.
cameraReady
=
false
,
this
.
isFullscreen
=
false
,
this
.
onTakePhoto
,
this
.
onToggleRecord
,
this
.
onRefresh
,
this
.
onToggleFullscreen
,
});
@override
Widget
build
(
BuildContext
context
)
{
return
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
_buildControlButton
(
icon:
Icons
.
refresh
,
onPressed:
onRefresh
,
tooltip:
'刷新画面'
,
enabled:
true
,
// 刷新按钮始终可用
),
SizedBox
(
width:
16
.
w
),
_buildControlButton
(
icon:
isFullscreen
?
Icons
.
fullscreen_exit
:
Icons
.
fullscreen
,
onPressed:
onToggleFullscreen
,
tooltip:
isFullscreen
?
'退出全屏'
:
'全屏放大'
,
enabled:
cameraReady
,
),
// _buildControlButton(
// icon: Icons.camera_alt,
// onPressed: cameraReady ? onTakePhoto : null,
// tooltip: '拍照',
// enabled: cameraReady,
// ),
// SizedBox(width: 16.w),
// _buildControlButton(
// icon: isRecording ? Icons.stop : Icons.videocam,
// onPressed: cameraReady ? onToggleRecord : null,
// tooltip: isRecording ? '停止录像' : '开始录像',
// isActive: isRecording,
// enabled: cameraReady,
// ),
],
);
}
/// 构建单个控制按钮
Widget
_buildControlButton
({
required
IconData
icon
,
VoidCallback
?
onPressed
,
String
?
tooltip
,
bool
isActive
=
false
,
bool
enabled
=
true
,
})
{
final
effectiveOpacity
=
enabled
?
1.0
:
0.35
;
return
Tooltip
(
message:
tooltip
??
''
,
child:
GestureDetector
(
onTap:
enabled
?
()
{
HapticFeedback
.
lightImpact
();
onPressed
?.
call
();
}
:
null
,
child:
Opacity
(
opacity:
effectiveOpacity
,
child:
AnimatedContainer
(
duration:
const
Duration
(
milliseconds:
200
),
width:
60
.
w
,
height:
60
.
w
,
decoration:
BoxDecoration
(
color:
isActive
?
const
Color
(
0xCCFF4444
)
:
const
Color
(
0x331E10B6
),
borderRadius:
BorderRadius
.
circular
(
30
.
r
),
border:
Border
.
all
(
color:
isActive
?
Colors
.
redAccent
:
Colors
.
white24
,
width:
1
,
),
boxShadow:
isActive
?
[
BoxShadow
(
color:
Colors
.
redAccent
.
withValues
(
alpha:
0.4
),
blurRadius:
12
.
r
,
spreadRadius:
2
,
),
]
:
null
,
),
child:
Icon
(
icon
,
color:
Colors
.
white
,
size:
32
.
w
,
),
),
),
),
);
}
}
lib/views/home/index/widgets/monitoring_screen.dart
deleted
100644 → 0
View file @
f7ca117d
This diff is collapsed.
Click to expand it.
lib/views/home/index/widgets/webrtc_fullscreen_page.dart
0 → 100644
View file @
9895a233
import
'package:flutter/material.dart'
;
import
'package:flutter_webrtc/flutter_webrtc.dart'
;
/// WebRTC 视频全屏播放页面
///
/// 全屏展示远程摄像头实时画面,点击任意位置退出全屏。
class
WebrtcFullscreenPage
extends
StatelessWidget
{
final
RTCVideoRenderer
renderer
;
const
WebrtcFullscreenPage
({
super
.
key
,
required
this
.
renderer
});
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
backgroundColor:
Colors
.
black
,
body:
GestureDetector
(
onTap:
()
=>
Navigator
.
of
(
context
).
pop
(),
child:
Stack
(
fit:
StackFit
.
expand
,
children:
[
// 全屏视频画面
Center
(
child:
RTCVideoView
(
renderer
,
objectFit:
RTCVideoViewObjectFit
.
RTCVideoViewObjectFitContain
,
),
),
// 顶部提示栏
Positioned
(
top:
0
,
left:
0
,
right:
0
,
child:
Container
(
padding:
const
EdgeInsets
.
fromLTRB
(
20
,
48
,
20
,
12
),
decoration:
const
BoxDecoration
(
gradient:
LinearGradient
(
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
colors:
[
Colors
.
black54
,
Colors
.
transparent
],
),
),
child:
const
Row
(
children:
[
Icon
(
Icons
.
fullscreen_exit
,
color:
Colors
.
white70
,
size:
20
),
SizedBox
(
width:
8
),
Text
(
'点击任意位置退出全屏'
,
style:
TextStyle
(
color:
Colors
.
white70
,
fontSize:
14
),
),
],
),
),
),
],
),
),
);
}
}
lib/views/home/index/widgets/webrtc_video_widget.dart
View file @
9895a233
...
@@ -3,6 +3,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
...
@@ -3,6 +3,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import
'package:flutter_webrtc/flutter_webrtc.dart'
;
import
'package:flutter_webrtc/flutter_webrtc.dart'
;
import
'../../../../services/webrtc_service.dart'
;
import
'../../../../services/webrtc_service.dart'
;
import
'webrtc_fullscreen_page.dart'
;
/// WebRTC 实时视频播放组件
/// WebRTC 实时视频播放组件
///
///
...
@@ -49,6 +50,9 @@ class WebrtcVideoWidget extends StatelessWidget {
...
@@ -49,6 +50,9 @@ class WebrtcVideoWidget extends StatelessWidget {
_buildVideoLayer
(),
_buildVideoLayer
(),
// 状态指示层
// 状态指示层
_buildStatusOverlay
(),
_buildStatusOverlay
(),
// 全屏按钮(仅连接状态下显示)
if
(
connectionState
==
WebrtcConnectionState
.
connected
)
_buildFullscreenButton
(
context
),
],
],
),
),
),
),
...
@@ -143,6 +147,36 @@ class WebrtcVideoWidget extends StatelessWidget {
...
@@ -143,6 +147,36 @@ class WebrtcVideoWidget extends StatelessWidget {
);
);
}
}
/// 全屏按钮(右下角)
Widget
_buildFullscreenButton
(
BuildContext
context
)
{
return
Positioned
(
right:
12
.
w
,
bottom:
12
.
h
,
child:
GestureDetector
(
onTap:
()
{
Navigator
.
of
(
context
).
push
(
MaterialPageRoute
(
builder:
(
_
)
=>
WebrtcFullscreenPage
(
renderer:
renderer
),
),
);
},
child:
Container
(
width:
40
.
w
,
height:
40
.
w
,
decoration:
BoxDecoration
(
color:
Colors
.
black38
,
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
),
child:
Icon
(
Icons
.
fullscreen
,
color:
Colors
.
white
,
size:
22
.
w
,
),
),
),
);
}
/// 未连接时的占位
/// 未连接时的占位
Widget
_buildPlaceholder
()
{
Widget
_buildPlaceholder
()
{
return
Center
(
return
Center
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment