사용자가 이름, 이메일, 코멘트를 입력하고, 앱을 평가하고 고객 서비스 만족도를 선택한 뒤, 뉴스레터 구독 여부를 설정하여 폼을 제출할 수 있습니다. 앱은 사용자 피드백을 쉽게 받을 수 있도록 설계.
import 'package:flutter/material.dart';
void main() {
runApp(FeedbackFormApp());
}
// 한 파일안에 여러개의 클래스를 만들 수 있다.
class FeedbackFormApp extends StatelessWidget {
const FeedbackFormApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, // 디너그 띠 X
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.redAccent),
),
home: FeedbackForm(), // 앱 시작 시 피드백 폼 표시
);
}
}
// 상태 변경 가능한 UI 선언
class FeedbackForm extends StatefulWidget {
const FeedbackForm({super.key});
@override
State<FeedbackForm> createState() => _FeedbackFormState();
}
class _FeedbackFormState extends State<FeedbackForm> {
final _formKey = GlobalKey<FormState>(); // 폼 상태를 추적하기 위한 글로벌 키
int _rating = 0;
bool _subscribe = false;
String _name = '';
String _email = '';
String _comments = '';
String _successMessage = '';
double _satisfaction = 0.0;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('FeedbackForm'),
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),
body: SingleChildScrollView(
// formField 터치시 소프트 키보드가 올라 옴. 여백 공간 적절히 줘야 함 (스크롤)
padding: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: '이름',
hintText: '홍길동',
border: OutlineInputBorder()),
validator: (value) {
// 입력 값 검증
if (value == null || value.isEmpty) {
return '이름을 입력해주세요.';
} else {
// 정상적으로 입력 했다면
return null;
}
}, // end of validator
onSaved: (value) {
_name = value!;
},
),
const SizedBox(height: 16.0),
TextFormField(
decoration: InputDecoration(
labelText: '이메일',
hintText: 'abc@naver.ocm',
border: OutlineInputBorder()),
validator: (value) {
// 입력 값 검증
if (value == null || value.isEmpty) {
return '이메일을 입력해주세요.';
} else {
// 정상적으로 입력 했다면
return null;
}
}, // end of validator
onSaved: (value) {
_email = value!;
},
),
const SizedBox(height: 16.0),
TextFormField(
maxLines: 4, // 여러줄 입력 가능
decoration: InputDecoration(
labelText: '코멘트',
hintText: '경혐을 공유해주세요',
border: OutlineInputBorder()),
validator: (value) {
// 입력 값 검증
if (value == null || value.isEmpty) {
return '코멘트를 입력해주세요.';
} else {
// 정상적으로 입력 했다면
return null;
}
}, // end of validator
onSaved: (value) {
_comments = value!;
},
),
const SizedBox(height: 24),
Text(
'우리 앱을 어떻게 평가하시겠습니까?',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(5, (index) {
return IconButton(
onPressed: () {
setState(() {
// 버그는 추후 수정
_rating = index + 1; // 선택한 점수로 설정
});
},
color: Colors.deepPurple,
icon: Icon(
_rating > index ? Icons.star : Icons.star_border),
);
}),
),
const SizedBox(height: 24),
Text(
'고객 서비스 만족도는 어느 정도입니까?',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary),
),
// 슬라이더
Slider(
value: _satisfaction,
// 추후 수정
min: 0,
max: 10,
onChanged: (value) {
setState(() {
print('value $value');
_satisfaction = value!;
});
},
divisions: 10,
// 슬라이더 구간
label: _satisfaction.toString(),
),
const SizedBox(height: 16),
SwitchListTile(
title: const Text('뉴스레터를 구독하시겠습니까?'),
value: _subscribe,
onChanged: (value) {
setState(() {
_subscribe = value;
});
},
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// 통과
_formKey.currentState!.save(); // 실행
// 변수에 값 할당
setState(() {
_successMessage = '제출이 완료 되었습니다';
});
} else {
// 실패
setState(() {
_successMessage = '';
});
}
},
child: const Text('제출'),
),
// 다트 문법 활용
if (_successMessage.isNotEmpty)
Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Text(
_successMessage,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: 16
),
),
)
],
),
),
),
),
);
}
}
! (널 무효화 연산자)
: 변수의 값이 널이 아님을 확신할 때 사용하는 연산자입니다
Material 3(또는 Material You)는 Google이 제안한 디자인 시스템의 세 번째 버전으로, 이전의 Material Design을 더욱 확장하여 사용자 맞춤형 경험을 강조하는 디자인 철학입니다.
- 앱의 색상 테마
- 앱바, 버튼, 슬라이더 등 기본 위젯의 스타일 변화
- 동적 색상 적용 및 팔레트 확장
- 애니메이션 및 모션 개선
- 위젯의 모서리 스타일과 접근성
등
실행 화면______
'Flutter' 카테고리의 다른 글
[Flutter] ListView 사용법과 주요 property (2) | 2024.11.11 |
---|---|
[Flutter] GlobalKey란 (0) | 2024.11.11 |
[Flutter] 플러터 기본기 다지기 - 3 (Form 위젯) (0) | 2024.11.11 |
[Flutter] 앱 레퍼런스 참고하여 Flutter로 화면 구현하기 2 (0) | 2024.11.07 |
[Flutter] SingleChildScrollView 위젯 (0) | 2024.11.07 |