-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from bunju20/develop
✨Feat: 문단 학습페이지 대본 페이지로, 대본 테스트 페이지 디자인 수정
- Loading branch information
Showing
7 changed files
with
372 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:flutter/material.dart'; | ||
import 'package:get/get.dart'; | ||
import 'package:get/get_core/src/get_main.dart'; | ||
import 'package:speech_to_text/speech_to_text.dart' as stt; | ||
import 'package:permission_handler/permission_handler.dart'; | ||
import 'package:earlips/viewModels/script/analyze_viewmodel.dart'; | ||
import '../../utilities/app_routes.dart'; | ||
|
||
|
||
|
||
class AnalyzeScreen extends StatefulWidget { | ||
@override | ||
_AnalyzeScreenState createState() => _AnalyzeScreenState(); | ||
} | ||
|
||
class _AnalyzeScreenState extends State<AnalyzeScreen> { | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return GestureDetector( | ||
onTap: () { | ||
FocusScope.of(context).requestFocus(FocusNode()); | ||
}, | ||
child: Scaffold( | ||
appBar: AppBar( | ||
title: Text('발음 및 빠르기 분석'), | ||
centerTitle: true, | ||
), | ||
body: SingleChildScrollView( | ||
child: Column( | ||
children: [ | ||
Container( | ||
alignment: Alignment.center, | ||
width: Get.width - 40, | ||
height: Get.height * 0.2, | ||
margin: EdgeInsets.all(20.0), | ||
padding: EdgeInsets.all(10.0), // 내부 여백을 추가합니다. | ||
decoration: BoxDecoration( | ||
color: Colors.white, // 배경색을 지정합니다. | ||
borderRadius: BorderRadius.circular(15.0), // 테두리 둥글기를 지정합니다. | ||
border: Border.all(color: Colors.white), // 테두리 색상을 지정합니다. 필요에 따라 변경 가능합니다. | ||
), | ||
child: _TopText(), | ||
), | ||
Stack( | ||
children: [ | ||
Container( | ||
alignment: Alignment.center, | ||
width: Get.width - 40, | ||
height: Get.height * 0.5, | ||
margin: EdgeInsets.all(20.0), | ||
padding: EdgeInsets.all(10.0), // 내부 여백을 추가합니다. | ||
decoration: BoxDecoration( | ||
color: Colors.white, // 배경색을 지정합니다. | ||
borderRadius: BorderRadius.circular(15.0), // 테두리 둥글기를 지정합니다. | ||
border: Border.all(color: Colors.white), // 테두리 색상을 지정합니다. 필요에 따라 변경 가능합니다. | ||
), | ||
child: TextStylingWidget(), | ||
), | ||
|
||
], | ||
), | ||
], | ||
), | ||
), | ||
floatingActionButton: Container( | ||
width: Get.width, | ||
alignment: Alignment.bottomCenter, | ||
|
||
child: FloatingActionButton( | ||
onPressed: () { | ||
Get.toNamed(Routes.HOME); | ||
}, | ||
child: Icon(Icons.home), // 홈 아이콘 사용 | ||
tooltip: '홈으로', // 롱 프레스 시 표시되는 텍스트 | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} | ||
|
||
class TextStylingWidget extends StatelessWidget { | ||
final AnalyzeViewModel model = Get.put(AnalyzeViewModel()); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return SingleChildScrollView( | ||
child: RichText( | ||
text: TextSpan( | ||
children: _buildTextSpans(), | ||
style: TextStyle(color: Colors.black, fontSize: 16), | ||
), | ||
textAlign: TextAlign.start, | ||
), | ||
); | ||
} | ||
|
||
List<TextSpan> _buildTextSpans() { | ||
List<TextSpan> spans = []; | ||
int globalWordIndex = 0; // 전체 단어에 대한 인덱스를 추적합니다. | ||
|
||
for (int i = 0; i < model.userSenten.length; i++) { | ||
final List<String> words = model.userSenten[i].split(' '); | ||
List<TextSpan> wordSpans = []; | ||
|
||
for (String word in words) { | ||
final bool isWrongWord = model.wrongWordIndexes.contains(globalWordIndex); | ||
wordSpans.add(TextSpan( | ||
text: "$word ", | ||
style: TextStyle( | ||
color: isWrongWord ? Colors.red : Colors.black, | ||
), | ||
)); | ||
globalWordIndex++; // 각 단어를 처리할 때마다 전체 단어 인덱스를 증가시킵니다. | ||
} | ||
|
||
spans.add(TextSpan( | ||
children: wordSpans, | ||
style: TextStyle( | ||
decoration: model.wrongFastIndexes.contains(i) ? TextDecoration.underline : TextDecoration.none, | ||
), | ||
)); | ||
spans.add(TextSpan(text: "\n")); // 문장 사이에 줄바꿈 추가 | ||
} | ||
|
||
return spans; | ||
} | ||
|
||
} | ||
|
||
class _TopText extends StatelessWidget { | ||
const _TopText({super.key}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Container( | ||
padding: EdgeInsets.all(10.0), | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: [ | ||
// 발음이 틀린 글씨에 대한 설명 | ||
RichText( | ||
text: TextSpan( | ||
style: TextStyle(fontSize: 16, color: Colors.black), | ||
children: [ | ||
TextSpan(text: '발음이 틀린 글씨는 빨간색으로 표시됩니다 ex)'), | ||
// 예시에 적용할 스타일 | ||
TextSpan( | ||
text: '강아지는 ', | ||
style: TextStyle(color: Colors.red), | ||
), | ||
TextSpan( | ||
text: '뛴다', | ||
), | ||
], | ||
), | ||
), | ||
Padding( | ||
padding: EdgeInsets.only(top: 20), | ||
), | ||
// 문장의 빠르기에 대한 설명 | ||
RichText( | ||
text: TextSpan( | ||
style: TextStyle(fontSize: 16, color: Colors.black), | ||
children: <TextSpan>[ | ||
TextSpan(text: '문장의 빠르기가 빠르거나 느리면 밑줄이 표시됩니다. ex)'), | ||
// 예시에 적용할 스타일 | ||
TextSpan( | ||
text: '강아지는 ', | ||
style: TextStyle(decoration: TextDecoration.underline), | ||
), | ||
TextSpan( | ||
text: '뛴다', | ||
style: TextStyle(decoration: TextDecoration.underline), | ||
), | ||
], | ||
), | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import 'package:earlips/utilities/style/color_styles.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:provider/provider.dart'; | ||
import 'package:earlips/viewModels/script/create_script_viewmodel.dart'; | ||
import 'package:get/get.dart'; | ||
|
||
class CreateScriptPage extends StatelessWidget { | ||
const CreateScriptPage({super.key}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return ChangeNotifierProvider<CreateScriptViewModel>( | ||
create: (_) => CreateScriptViewModel(), | ||
child: Consumer<CreateScriptViewModel>( | ||
builder: (context, model, child) => Scaffold( | ||
appBar: AppBar( | ||
title: const Text('문단교정'), | ||
centerTitle: true, | ||
actions: <Widget>[ | ||
TextButton( | ||
onPressed: model.complete, | ||
child: const Text( | ||
'완료', | ||
style: TextStyle( | ||
color: Colors.black, | ||
fontSize: 20, | ||
), | ||
), | ||
), | ||
], | ||
), | ||
body: Stack( | ||
// Stack 위젯을 사용하여 Positioned를 올바르게 배치합니다. | ||
children: [ | ||
Column( | ||
// 기존의 Column 구조를 Stack 내에 배치합니다. | ||
children: [ | ||
Expanded( | ||
flex: 1, | ||
child: Padding( | ||
padding: const EdgeInsets.all(10.0), | ||
child: TextField( | ||
controller: model.writedTextController, | ||
expands: true, | ||
maxLines: null, | ||
decoration: InputDecoration( | ||
hintText: '대본을 입력하세요...', | ||
fillColor: Colors.white, | ||
filled: true, | ||
border: OutlineInputBorder( | ||
borderRadius: BorderRadius.circular(15.0), | ||
borderSide: BorderSide.none, | ||
), | ||
), | ||
textAlignVertical: TextAlignVertical.top, | ||
), | ||
), | ||
), | ||
Expanded( | ||
flex: 1, | ||
child: Padding( | ||
padding: const EdgeInsets.fromLTRB(25, 20, 25, 100), | ||
child: Container( | ||
padding: const EdgeInsets.all(20.0), | ||
width: Get.width * 0.8, | ||
decoration: BoxDecoration( | ||
color: Colors.white, | ||
borderRadius: BorderRadius.circular(15.0), | ||
boxShadow: [ | ||
BoxShadow( | ||
color: Colors.grey.withOpacity(0.5), | ||
spreadRadius: 1, | ||
blurRadius: 6, | ||
offset: const Offset(0, 3), | ||
), | ||
], | ||
), | ||
child: SingleChildScrollView( | ||
child: Text( | ||
model.voicedTextController.text, | ||
style: const TextStyle(fontSize: 16), | ||
), | ||
), | ||
), | ||
), | ||
), | ||
], | ||
), | ||
Positioned( | ||
// Positioned 위젯으로 사용자 정의 FloatingActionButton을 배치합니다. | ||
bottom: 20, | ||
left: 0, | ||
right: 0, | ||
child: Align( | ||
alignment: Alignment.bottomCenter, | ||
child: Ink( | ||
decoration: BoxDecoration( | ||
color: model.isRecording ? Colors.red : Colors.blue, | ||
borderRadius: BorderRadius.circular(40), | ||
), | ||
child: InkWell( | ||
borderRadius: BorderRadius.circular(40), | ||
onTap: model.toggleRecording, | ||
child: Padding( | ||
padding: const EdgeInsets.all(20), | ||
child: Icon( | ||
model.isRecording ? Icons.stop : Icons.mic, | ||
size: 30, | ||
color: Colors.white, | ||
), | ||
), | ||
), | ||
), | ||
), | ||
), | ||
], | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} |
Oops, something went wrong.