From cc290d8627453677915cb08b66714cbd1f577cde Mon Sep 17 00:00:00 2001 From: Jungwoo <108061510+jwson-automation@users.noreply.github.com> Date: Sun, 25 Aug 2024 22:47:54 +0900 Subject: [PATCH] fix voice out put screen for desing --- lib/core/TopScreen.dart | 2 +- .../voiceOutput/VoiceOutputScreen.dart | 23 +++++- .../provider/CategoryIondexProvider.dart | 14 ++++ .../voiceOutput/widget/VoiceOutputButton.dart | 29 ++++++++ .../widget/VoiceOutputCategoryListView.dart | 65 ++++++++++++++++ .../widget/VoiceOutputDescriptionTextBox.dart | 49 ++++++++++++ .../voiceOutput/widget/VoiceOutputWidget.dart | 74 ------------------- pubspec.yaml | 2 +- 8 files changed, 179 insertions(+), 79 deletions(-) create mode 100644 lib/feature/voiceOutput/provider/CategoryIondexProvider.dart create mode 100644 lib/feature/voiceOutput/widget/VoiceOutputButton.dart create mode 100644 lib/feature/voiceOutput/widget/VoiceOutputCategoryListView.dart create mode 100644 lib/feature/voiceOutput/widget/VoiceOutputDescriptionTextBox.dart delete mode 100644 lib/feature/voiceOutput/widget/VoiceOutputWidget.dart diff --git a/lib/core/TopScreen.dart b/lib/core/TopScreen.dart index 2ec6d68..02c2175 100644 --- a/lib/core/TopScreen.dart +++ b/lib/core/TopScreen.dart @@ -23,7 +23,7 @@ class TopScreen extends ConsumerWidget { final selectedIndex = ref.watch(selectedIndexProvider); final List pages = [ - const VoiceOutputScreen(), + VoiceOutputScreen(), const PoliceMapScreen(), const MyPageScreen(), ]; diff --git a/lib/feature/voiceOutput/VoiceOutputScreen.dart b/lib/feature/voiceOutput/VoiceOutputScreen.dart index 953798d..61ae8c6 100644 --- a/lib/feature/voiceOutput/VoiceOutputScreen.dart +++ b/lib/feature/voiceOutput/VoiceOutputScreen.dart @@ -1,7 +1,9 @@ +import 'package:blueberry_flutter_template/feature/voiceOutput/widget/VoiceOutputButton.dart'; +import 'package:blueberry_flutter_template/feature/voiceOutput/widget/VoiceOutputCategoryListView.dart'; +import 'package:blueberry_flutter_template/feature/voiceOutput/widget/VoiceOutputDescriptionTextBox.dart'; +import 'package:blueberry_flutter_template/utils/AppTextStyle.dart'; import 'package:flutter/material.dart'; -import './widget/VoiceOutputWidget.dart'; - class VoiceOutputScreen extends StatelessWidget { static const name = 'VoiceOutputScreen'; @@ -15,10 +17,25 @@ class VoiceOutputScreen extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded(child: VoiceOutputWidget()), + Expanded(flex: 1, child: VoiceOutputTitleText()), + Expanded(flex: 4, child: VoiceOutputCategoryListView()), + Expanded(flex: 1, child: VoiceOutputDescriptionTextBox()), + Expanded(flex: 5, child: VoiceOutputButton()), ], ), ), ); } } + +class VoiceOutputTitleText extends StatelessWidget { + const VoiceOutputTitleText({super.key}); + + @override + Widget build(BuildContext context) { + return const Text( + '남자 음성 출력 하기', + style: black24TextStyle, + ); + } +} diff --git a/lib/feature/voiceOutput/provider/CategoryIondexProvider.dart b/lib/feature/voiceOutput/provider/CategoryIondexProvider.dart new file mode 100644 index 0000000..ebbde6c --- /dev/null +++ b/lib/feature/voiceOutput/provider/CategoryIondexProvider.dart @@ -0,0 +1,14 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class CategoryIndexNotifier extends StateNotifier { + CategoryIndexNotifier() : super(0); + + void setIndex(int index) { + state = index; + } +} + +final categoryIndexProvider = + StateNotifierProvider((ref) { + return CategoryIndexNotifier(); +}); diff --git a/lib/feature/voiceOutput/widget/VoiceOutputButton.dart b/lib/feature/voiceOutput/widget/VoiceOutputButton.dart new file mode 100644 index 0000000..1eb9654 --- /dev/null +++ b/lib/feature/voiceOutput/widget/VoiceOutputButton.dart @@ -0,0 +1,29 @@ +import 'package:blueberry_flutter_template/feature/voiceOutput/provider/CategoryIondexProvider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class VoiceOutputButton extends ConsumerWidget { + const VoiceOutputButton({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final categoryIndex = ref.watch(categoryIndexProvider); + + return CircleAvatar( + backgroundColor: Colors.black, + radius: 50, + child: IconButton( + onPressed: () { + print('음성 출력: ${categoryIndex}'); + }, + icon: const Icon(Icons.volume_up), + // 마이크 아이콘 + iconSize: 50, + // 아이콘 크기 + color: Colors.white, + // 아이콘 색상 + splashRadius: 30, // 클릭 반경 + ), + ); + } +} diff --git a/lib/feature/voiceOutput/widget/VoiceOutputCategoryListView.dart b/lib/feature/voiceOutput/widget/VoiceOutputCategoryListView.dart new file mode 100644 index 0000000..693066b --- /dev/null +++ b/lib/feature/voiceOutput/widget/VoiceOutputCategoryListView.dart @@ -0,0 +1,65 @@ +import 'package:blueberry_flutter_template/feature/voiceOutput/provider/CategoryIondexProvider.dart'; +import 'package:flutter/material.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class VoiceOutputCategoryListView extends ConsumerWidget { + const VoiceOutputCategoryListView({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + // 카테고리 데이터를 리스트로 정의 + final categories = ['화내는 남편', '놀러온 남자', '데이트 준비중', '조직폭력배 남자']; + + return CarouselSlider( + options: CarouselOptions( + height: 250.0, // 슬라이더 높이 + enableInfiniteScroll: false, // 무한 스크롤 비활성화 + enlargeCenterPage: true, // 중앙의 아이템 확대 + viewportFraction: 0.4, // 각 아이템의 크기 비율 + onPageChanged: (index, reason) { + ref.read(categoryIndexProvider.notifier).setIndex(index); + }, + ), + items: categories.map((category) { + return Builder( + builder: (BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + flex: 2, // 여유 공간의 2/3 사용 + child: CircleAvatar( + radius: 80, // 원의 크기 조정 + backgroundColor: Colors.blue, // 원의 배경색 + child: Text( + category[0], // 카테고리 이름의 첫 글자 + style: const TextStyle( + color: Colors.white, // 텍스트 색상 + fontSize: 40, // 텍스트 크기 + fontWeight: FontWeight.bold, // 텍스트 두께 + ), + ), + ), + ), + const SizedBox(height: 10), // 텍스트와 원 사이의 간격 + Expanded( + flex: 1, // 여유 공간의 1/3 사용 + child: Text( + category, // 카테고리 이름 표시 + textAlign: TextAlign.center, // 텍스트 가운데 정렬 + softWrap: true, // 텍스트 자동 줄바꿈 + overflow: TextOverflow.ellipsis, // 텍스트가 길면 생략 표시 + maxLines: 2, // 최대 줄 수 설정 + style: const TextStyle(fontSize: 14), // 텍스트 스타일 설정 + ), + ), + ], + ); + }, + ); + }).toList(), + ); + } +} + diff --git a/lib/feature/voiceOutput/widget/VoiceOutputDescriptionTextBox.dart b/lib/feature/voiceOutput/widget/VoiceOutputDescriptionTextBox.dart new file mode 100644 index 0000000..0039082 --- /dev/null +++ b/lib/feature/voiceOutput/widget/VoiceOutputDescriptionTextBox.dart @@ -0,0 +1,49 @@ +import 'package:blueberry_flutter_template/feature/voiceOutput/provider/CategoryIondexProvider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class VoiceOutputDescriptionTextBox extends ConsumerWidget { + const VoiceOutputDescriptionTextBox({ + super.key, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final categoryIndex = ref.watch(categoryIndexProvider); + + final descriptionList = [ + '너는 항상 왜 그러는 거야?', + '늦었네..?', + '오늘도 수고 많았어~', + '뭐? 어떤 놈인데?', + ]; + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 60), + child: Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.grey.shade300, + borderRadius: BorderRadius.circular(14), + ), + child: Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const CircleAvatar( + backgroundColor: Colors.white, + child: Icon(Icons.person, color: Colors.black)), + Text( + descriptionList[categoryIndex], + style: const TextStyle( + fontSize: 16, + color: Colors.black, + ), + ), + const SizedBox(width: 16), + ], + ), + )), + ); + } +} diff --git a/lib/feature/voiceOutput/widget/VoiceOutputWidget.dart b/lib/feature/voiceOutput/widget/VoiceOutputWidget.dart deleted file mode 100644 index 415220e..0000000 --- a/lib/feature/voiceOutput/widget/VoiceOutputWidget.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'package:audioplayers/audioplayers.dart'; -import 'package:blueberry_flutter_template/gen/assets.gen.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; - -import '../provider/VoiceOutputProvider.dart'; - -class VoiceOutputWidget extends ConsumerWidget { - const VoiceOutputWidget({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final list = ref.watch(voiceOutputProvider); - return list.when( - data: (data) { - return _buildListView(data); - }, - loading: () => const Center(child: CircularProgressIndicator()), - error: (error, stackTrace) { - return Center(child: Text('Error: $error')); - }, - ); - } - - Widget _buildListView(List data) { - return Container( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: data - .map((text) => Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: VoiceOutputRow(text: text, index: data.indexOf(text)), - )) - .toList(), - ), - ); - } -} - -class VoiceOutputRow extends StatelessWidget { - final String text; - final int index; - final player = AudioPlayer(); - - VoiceOutputRow({super.key, required this.text, required this.index}); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Text( - text, - style: const TextStyle(fontSize: 18), - textAlign: TextAlign.left, - ), - ), - const SizedBox(width: 8), - ElevatedButton( - onPressed: () { - final source = AssetSource("voice/voice_${index+1}.mp3"); - player.play(source); - }, - child: const Text("button"), - ), - ], - ), - ); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index 11b8310..f3ae1d3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,7 +38,7 @@ dependencies: # UI cupertino_icons: ^1.0.6 - carousel_slider: ^4.2.1 + carousel_slider: ^5.0.0 cached_network_image: ^3.3.1 flutter_rating_bar: ^4.0.1 pinput: ^4.0.0