import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/flutter_tts_test_controller.dart'; import '../../../data/services/flutter_tts_service.dart'; /// Flutter TTS测试视图,演示如何使用FlutterTtsService class FlutterTtsTestView extends GetView { const FlutterTtsTestView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Flutter TTS Test'), centerTitle: true, ), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 播放控制卡片 Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Playback Controls', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Obx(() { final isPlaying = controller.isPlaying; return ElevatedButton.icon( onPressed: isPlaying ? null : () => _playAllTexts(), icon: isPlaying ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.playlist_play), label: Text(isPlaying ? 'Playing...' : 'Play All'), style: ElevatedButton.styleFrom( backgroundColor: Colors.green, foregroundColor: Colors.white, ), ); }), Obx(() { final isActive = controller.ttsState != TtsState.stopped; return ElevatedButton.icon( onPressed: isActive ? () => controller.stop() : null, icon: const Icon(Icons.stop), label: const Text('Stop'), style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), ); }), ], ), ], ), ), ), const SizedBox(height: 16), // 语音选择卡片 Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Voice Selection', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Obx(() { final voices = controller.voices; final currentVoice = controller.currentVoice; if (voices.isEmpty) { return const Padding( padding: EdgeInsets.all(8.0), child: Text( 'No voices available. Please check TTS settings on your device.', style: TextStyle( color: Colors.red, fontStyle: FontStyle.italic, ), ), ); } return DropdownButtonFormField( decoration: const InputDecoration( labelText: 'Select Voice', border: OutlineInputBorder(), contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), ), value: currentVoice.isNotEmpty ? currentVoice : null, items: voices.map((voice) { final name = voice['name'] ?? 'Unknown'; final locale = voice['locale'] ?? ''; return DropdownMenuItem( value: name, child: Text('$name ${locale.isNotEmpty ? '($locale)' : ''}'), ); }).toList(), onChanged: controller.isPlaying ? null : (value) { if (value != null) { controller.setVoice(value); } }, isExpanded: true, hint: const Text('Select a voice'), ); }), ], ), ), ), const SizedBox(height: 16), // 播报内容列表卡片 Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Sample Texts', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), // 预设的播报内容 ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: _getSampleTexts().length, separatorBuilder: (context, index) => const Divider(height: 1), itemBuilder: (context, index) { final text = _getSampleTexts()[index]; return Obx(() { final isPlaying = controller.isPlaying; final isCurrentPlaying = controller.isPlaying && controller.currentText == text; return ListTile( title: Text( text, style: TextStyle( fontWeight: isCurrentPlaying ? FontWeight.bold : FontWeight.normal, color: isCurrentPlaying ? Colors.blue : null, ), ), leading: CircleAvatar( backgroundColor: isCurrentPlaying ? Colors.blue : Colors.blue.shade100, radius: 18, child: Icon( isCurrentPlaying ? Icons.volume_up : Icons.play_arrow, color: isCurrentPlaying ? Colors.white : Colors.blue, size: 20, ), ), onTap: isPlaying ? null : () => controller.speak(text), enabled: !isPlaying, tileColor: isCurrentPlaying ? Colors.blue.withOpacity(0.1) : null, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), side: isCurrentPlaying ? const BorderSide(color: Colors.blue, width: 1) : BorderSide.none, ), ); }); }, ), ], ), ), ), const SizedBox(height: 16), // 状态显示卡片 Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Status', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Obx(() { final state = controller.ttsState; final stateText = _getTtsStateText(state); final stateColor = _getTtsStateColor(state); return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: stateColor.withOpacity(0.1), borderRadius: BorderRadius.circular(8), border: Border.all(color: stateColor.withOpacity(0.3)), ), child: Row( children: [ Icon( _getTtsStateIcon(state), color: stateColor, ), const SizedBox(width: 8), Text( 'Current Status: $stateText', style: TextStyle( color: stateColor, fontWeight: FontWeight.bold, ), ), ], ), ); }), ], ), ), ), ], ), ), ), ); } // 连续播放所有文本 void _playAllTexts() { // 使用控制器的连续播放功能播放所有文本 controller.speakTexts(_getSampleTexts()); } // 获取TTS状态文本 String _getTtsStateText(TtsState state) { switch (state) { case TtsState.playing: return 'Playing'; case TtsState.paused: return 'Paused'; case TtsState.stopped: return 'Stopped'; default: return 'Unknown'; } } // 获取TTS状态颜色 Color _getTtsStateColor(TtsState state) { switch (state) { case TtsState.playing: return Colors.green; case TtsState.paused: return Colors.orange; case TtsState.stopped: return Colors.grey; default: return Colors.grey; } } // 获取TTS状态图标 IconData _getTtsStateIcon(TtsState state) { switch (state) { case TtsState.playing: return Icons.volume_up; case TtsState.paused: return Icons.pause; case TtsState.stopped: return Icons.stop; default: return Icons.help_outline; } } // 获取示例文本 List _getSampleTexts() { return [ 'This is a Flutter TTS test. Please listen to the synthesis effect.', '这是Flutter TTS测试,请听取合成效果。', 'Flutter TTS supports various voices and parameter adjustments.', 'Flutter TTS支持多种语音和参数调节,可以根据需要进行设置。', ]; } }