import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/services.dart'; class PoetScreen extends StatefulWidget { final int selectedIndex; const PoetScreen({super.key, required this.selectedIndex}); @override State createState() => _PoetScreenState(); } class _PoetScreenState extends State with WidgetsBindingObserver { late String _backgroundImage; final AudioPlayer _audioPlayer = AudioPlayer(); bool _isPlaying = false; Duration _duration = Duration.zero; Duration _position = Duration.zero; PlayerState? _playerState; late Source _source; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); _setSystemUIOverlayStyle(); _backgroundImage = 'assets/images/subsets/Sub_${(widget.selectedIndex + 1).toString().padLeft(2, '0')}.webp'; _source = AssetSource('audio/${(widget.selectedIndex + 1).toString()}.mp3'); _audioPlayer.onPlayerStateChanged.listen((state) { if (mounted) { setState(() { _isPlaying = state == PlayerState.playing; _playerState = state; }); } if (state == PlayerState.completed) { _audioPlayer.seek(Duration.zero); setState(() { _position = Duration.zero; }); } }); _audioPlayer.onDurationChanged.listen((newDuration) { if (mounted) { setState(() { _duration = newDuration; }); } }); _audioPlayer.onPositionChanged.listen((newPosition) { if (mounted) { setState(() { _position = newPosition; }); } }); _setAudio(); } void _setSystemUIOverlayStyle() { if (defaultTargetPlatform == TargetPlatform.android) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); } } @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { _setSystemUIOverlayStyle(); } } Future _setAudio() async { try { await _audioPlayer.setSource(_source); _audioPlayer.play(_source); } catch (e) { // Handle error, e.g., show a snackbar print("Error setting audio source: $e"); } } @override void dispose() { WidgetsBinding.instance.removeObserver(this); // if (defaultTargetPlatform == TargetPlatform.android) { // SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); // } _audioPlayer.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 배경 이미지 Positioned.fill( child: Image.asset( _backgroundImage, fit: BoxFit.cover, ), ), // 메인 콘텐츠 SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 상단 바 (뒤로가기, 제목, 새로고침) Padding( padding: const EdgeInsets.only(top: 50.0,left: 25), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildCircularImageButton('assets/images/ui/UI_Back.webp', () { // 이 버튼을 누르면 이전 화면으로 돌아갑니다. Navigator.pop(context); }, size: 90, imageSize: 90), // _buildCircularImageButton('assets/images/ui/UI_Replay.webp', () { // // Refresh action here // }, size: 100, imageSize: 100), ], ), ), _buildMusicControls(), ], ), ), ), ], ), ); } Widget _buildMusicControls() { return Column( children: [ Slider( min: 0, max: _duration.inSeconds.toDouble(), value: _position.inSeconds.toDouble(), onChanged: (value) async { final position = Duration(seconds: value.toInt()); await _audioPlayer.seek(position); }, activeColor: const Color(0xFFF07B41), inactiveColor: Colors.grey, ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(_formatDuration(_position)), Text(_formatDuration(_duration - _position)), ], ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildCircularImageButton('assets/images/ui/UI_5minus.webp', () { final newPosition = _position - const Duration(seconds: 5); _audioPlayer.seek(newPosition > Duration.zero ? newPosition : Duration.zero); }), const SizedBox(width: 100), _buildPlayPauseButton(), const SizedBox(width: 100), _buildCircularImageButton('assets/images/ui/UI_5plus.webp', () { final newPosition = _position + const Duration(seconds: 5); _audioPlayer.seek(newPosition < _duration ? newPosition : _duration); }), ], ), ], ); } Widget _buildPlayPauseButton() { return GestureDetector( onTap: () { if (_isPlaying) { _audioPlayer.pause(); } else { if (_playerState == PlayerState.completed) { _audioPlayer.play(_source); } else { _audioPlayer.resume(); } } }, child: Container( width: 150, height: 150, child: Center( child: _isPlaying ? Image.asset( 'assets/images/ui/UI_Pause.webp', width: 191, height: 190, ) : Image.asset( 'assets/images/ui/UI_Play.webp', width: 191, height: 190, ), ), ), ); } Widget _buildCircularImageButton(String imagePath, VoidCallback onPressed, {double size = 100, double imageSize = 100}) { return GestureDetector( onTap: onPressed, child: Container( width: size, height: size, child: Center( child: Image.asset( imagePath, width: imageSize, height: imageSize, ), ), ), ); } String _formatDuration(Duration duration) { String twoDigits(int n) => n.toString().padLeft(2, '0'); final hours = twoDigits(duration.inHours); final minutes = twoDigits(duration.inMinutes.remainder(60)); final seconds = twoDigits(duration.inSeconds.remainder(60)); return [ if (duration.inHours > 0) hours, minutes, seconds, ].join(':'); } }