MIF_E31231623/android/wisata_app/lib/screens/video_page.dart

200 lines
6.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
class VideoPage extends StatefulWidget {
const VideoPage({
super.key,
required this.title,
required this.videoPath,
});
final String title;
final String videoPath;
@override
State<VideoPage> createState() => _VideoPageState();
}
class _VideoPageState extends State<VideoPage> {
late final VideoPlayerController _controller;
late final Future<void> _initializeVideo;
bool _fullscreen = false;
@override
void initState() {
super.initState();
final uri = Uri.tryParse(widget.videoPath);
_controller = uri != null && uri.hasScheme
? VideoPlayerController.networkUrl(uri)
: VideoPlayerController.asset(widget.videoPath);
_initializeVideo = _controller.initialize().then((_) {
_controller
..setLooping(true)
..play();
if (mounted) {
setState(() {});
}
});
}
@override
void dispose() {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
SystemChrome.setPreferredOrientations(DeviceOrientation.values);
_controller.dispose();
super.dispose();
}
void _togglePlayPause() {
setState(() {
_controller.value.isPlaying ? _controller.pause() : _controller.play();
});
}
Future<void> _toggleFullscreen() async {
setState(() => _fullscreen = !_fullscreen);
if (_fullscreen) {
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
await SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
return;
}
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
await SystemChrome.setPreferredOrientations(DeviceOrientation.values);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
fit: StackFit.expand,
children: [
Center(
child: FutureBuilder<void>(
future: _initializeVideo,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const DecoratedBox(
decoration: BoxDecoration(color: Colors.black),
child: Center(
child: CircularProgressIndicator(
color: Color(0xFF14B8C4),
),
),
);
}
if (snapshot.hasError || _controller.value.hasError) {
return Padding(
padding: const EdgeInsets.all(24),
child: Text(
'Video wisata gagal dimuat.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Colors.white,
fontWeight: FontWeight.w800,
),
),
);
}
return SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
child: SizedBox(
width: _controller.value.size.width,
height: _controller.value.size.height,
child: VideoPlayer(_controller),
),
),
);
},
),
),
const DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xCC000000),
Color(0x22000000),
Color(0xBB000000),
],
),
),
),
SafeArea(
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 12, 20),
child: Column(
children: [
Row(
children: [
IconButton.filledTonal(
tooltip: 'Kembali',
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.arrow_back_rounded),
),
const SizedBox(width: 10),
Expanded(
child: Text(
widget.title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style:
Theme.of(context).textTheme.titleLarge?.copyWith(
color: Colors.white,
fontWeight: FontWeight.w900,
),
),
),
IconButton.filledTonal(
tooltip:
_fullscreen ? 'Keluar fullscreen' : 'Fullscreen',
onPressed: _toggleFullscreen,
icon: Icon(
_fullscreen
? Icons.fullscreen_exit_rounded
: Icons.fullscreen_rounded,
),
),
],
),
const Spacer(),
ValueListenableBuilder<VideoPlayerValue>(
valueListenable: _controller,
builder: (context, value, child) {
return IconButton.filled(
tooltip: value.isPlaying ? 'Jeda' : 'Putar',
onPressed:
value.isInitialized ? _togglePlayPause : null,
iconSize: 40,
style: IconButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: const Color(0xFF0F4C81),
padding: const EdgeInsets.all(18),
),
icon: Icon(
value.isPlaying
? Icons.pause_rounded
: Icons.play_arrow_rounded,
),
);
},
),
],
),
),
),
],
),
);
}
}