216 lines
7.3 KiB
Dart
216 lines
7.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
|
class SelectionModal extends StatefulWidget {
|
|
final String title;
|
|
final List<String> currentSelected;
|
|
final String currentOtherText;
|
|
final Function(List<String>, String) onComplete;
|
|
final bool isSingleSelection;
|
|
final List<String> itemList;
|
|
|
|
const SelectionModal({
|
|
super.key,
|
|
required this.title,
|
|
required this.currentSelected,
|
|
required this.currentOtherText,
|
|
required this.onComplete,
|
|
this.isSingleSelection = false,
|
|
required this.itemList,
|
|
});
|
|
|
|
@override
|
|
State<SelectionModal> createState() => _SelectionModalState();
|
|
}
|
|
|
|
class _SelectionModalState extends State<SelectionModal> {
|
|
late List<String> _tempSelected;
|
|
final TextEditingController _otherController = TextEditingController();
|
|
bool _isOtherSelected = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_tempSelected = List.from(widget.currentSelected);
|
|
_otherController.text = widget.currentOtherText;
|
|
|
|
// "기타"가 선택되어 있는지 확인 (여기서는 단순히 리스트에 있는지로 판단하지 않고,
|
|
// "기타"라는 항목 텍스트 자체를 체크하거나, 외부에서 넘겨받은 텍스트가 있으면 체크)
|
|
// *로직 수정*: itemList에 "기타"가 포함되어 있다면 그것을 기준으로 함.
|
|
if (_tempSelected.contains("기타")) {
|
|
_isOtherSelected = true;
|
|
} else if (widget.currentOtherText.isNotEmpty) {
|
|
// 기존 로직상 기타 텍스트가 있으면 기타가 선택된 것으로 간주할 수도 있음
|
|
// 하지만 리스트 기반이므로 명시적으로 "기타" 아이템이 있어야 함.
|
|
// 여기서는 단순화하여 UI 상태만 초기화.
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_otherController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void _onItemTap(String item) {
|
|
setState(() {
|
|
if (item == "기타") {
|
|
if (widget.isSingleSelection) {
|
|
_tempSelected.clear();
|
|
_tempSelected.add(item);
|
|
_isOtherSelected = true;
|
|
} else {
|
|
if (_tempSelected.contains(item)) {
|
|
_tempSelected.remove(item);
|
|
_isOtherSelected = false;
|
|
} else {
|
|
_tempSelected.add(item);
|
|
_isOtherSelected = true;
|
|
}
|
|
}
|
|
} else {
|
|
if (widget.isSingleSelection) {
|
|
_tempSelected.clear();
|
|
_tempSelected.add(item);
|
|
// 단일 선택에서 다른거 누르면 기타 해제
|
|
_isOtherSelected = false;
|
|
} else {
|
|
if (_tempSelected.contains(item)) {
|
|
_tempSelected.remove(item);
|
|
} else {
|
|
_tempSelected.add(item);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
height: MediaQuery.of(context).size.height * 0.7,
|
|
decoration: const BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
SizedBox(height: 20.h),
|
|
Text(
|
|
widget.title,
|
|
style: TextStyle(
|
|
fontSize: 18.sp,
|
|
fontWeight: FontWeight.bold,
|
|
fontFamily: 'SCDream',
|
|
),
|
|
),
|
|
SizedBox(height: 20.h),
|
|
Expanded(
|
|
child: ListView.builder(
|
|
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
|
itemCount: widget.itemList.length,
|
|
itemBuilder: (context, index) {
|
|
final item = widget.itemList[index];
|
|
final isSelected = _tempSelected.contains(item);
|
|
|
|
return Column(
|
|
children: [
|
|
ListTile(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(10.r),
|
|
side: BorderSide(
|
|
color: isSelected
|
|
? const Color(0xFFFF7500)
|
|
: Colors.grey[300]!,
|
|
),
|
|
),
|
|
tileColor: isSelected
|
|
? const Color(0xFFFF7500).withValues(
|
|
alpha: 0.1,
|
|
) // Fixed deprecated
|
|
: Colors.white,
|
|
title: Text(
|
|
item,
|
|
style: TextStyle(
|
|
fontFamily: 'SCDream',
|
|
fontSize: 15.sp,
|
|
color: isSelected
|
|
? const Color(0xFFFF7500)
|
|
: Colors.black,
|
|
fontWeight: isSelected
|
|
? FontWeight.bold
|
|
: FontWeight.normal,
|
|
),
|
|
),
|
|
trailing: isSelected
|
|
? Icon(
|
|
Icons.check,
|
|
color: const Color(0xFFFF7500),
|
|
size: 20.w,
|
|
)
|
|
: null,
|
|
onTap: () => _onItemTap(item),
|
|
),
|
|
SizedBox(height: 10.h),
|
|
// 기타 선택 시 입력창 표시
|
|
if (item == "기타" && isSelected)
|
|
Padding(
|
|
padding: EdgeInsets.only(
|
|
left: 10.w,
|
|
right: 10.w,
|
|
bottom: 20.h,
|
|
),
|
|
child: TextField(
|
|
controller: _otherController,
|
|
decoration: const InputDecoration(
|
|
hintText: '내용을 입력해주세요',
|
|
hintStyle: TextStyle(
|
|
fontFamily: 'SCDream',
|
|
color: Colors.grey,
|
|
),
|
|
border: UnderlineInputBorder(),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(20.w),
|
|
child: SizedBox(
|
|
width: double.infinity,
|
|
height: 50.h,
|
|
child: ElevatedButton(
|
|
onPressed: () {
|
|
widget.onComplete(
|
|
_tempSelected,
|
|
_isOtherSelected ? _otherController.text : '',
|
|
);
|
|
Navigator.pop(context);
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: const Color(0xFFFF7500),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(10.r),
|
|
),
|
|
),
|
|
child: Text(
|
|
'선택 완료',
|
|
style: TextStyle(
|
|
fontFamily: 'SCDream',
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16.sp,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|