Because multi_dropdown >=2.0.2 <3.0.0-beta.1 depends on http ^1.1.0 and every version of internet_file depends on http ^0.13.4, multi_dropdown >=2.0.2 <3.0.0-beta.1 is incompatible with internet_file.
So, because company depends on both multi_dropdown ^2.1.4 and internet_file any, version solving failed.
에러 배경 : pdf를 웹 프로젝트에 그리려고 하니 pdfx와 같이 사용하는 internet_file 패키지와 multi_dropdown 패키지의 버전이 충돌하여 multi_dropdown 패키지의 버전을 최신화 해야함.
최신화 하니까 다 빨간줄이다.
import 'package:multi_dropdown/multiselect_dropdown.dart';
=> import 'package:multi_dropdown/multi_dropdown.dart';
MultiSelectDropDown => MultiDropdown
MultiSelectDropDown is now MultiDropdown.
options => items
ValueItem => DropdownItem
ValueItem is now DropdownItem. It now supports disabled & selected properties.
chipConfig: ChipConfig(
wrapType: WrapType.scroll,
=>
chipDecoration: ChipDecoration(
wrap: true,
selectedOptions => controller
onOptionSelected => onSelectionChange
selectionType => singleSelect: false,
selectedOptionIcon: Icon(
Icons.check_circle,
color: primaryDark,
),
=>
dropdownItemDecoration: DropdownItemDecoration(
selectedIcon: Icon(
Icons.check_circle,
color: primaryDark,
),
),
이렇게 치환하니 대부분 되었다.
다음문제는 items가 업데이트가 되지 않는 문제가 있었는데
파라미터로 받아온 데이터를 가공하려니 안되서 내부를 StatefulWidget으로 변경후 _controller를 만들었다. 이것도 새로 추가된 방법이다.
final _controller = MultiSelectController<int>();
@override
void initState() {
super.initState();
// 1) 전체 아이템 세팅
_controller.setItems(widget.optionList);
// 2) 초기 선택
for (final sel in widget.initialSelection) {
_controller.selectWhere((item) => item.value == sel.value);
}
// 3) “현재 컨트롤러에 선택된 아이템”을 onPressed로 전달
final selectedNow = _controller
.getSelectedItems() // List<DropdownItem<int>>
.map((dropdownItem) => dropdownItem.value)
.toList();
widget.onPressed(selectedNow);
}
@override
Widget build(BuildContext context) {
return MultiDropdown<int>(
controller: _controller,
items: widget.optionList,
onSelectionChange: (List<int> selected) {
widget.onPressed(selected);
},
(...)
이렇게 해도 initialSelection이 안나타났다. 이유를 모르겠던 그때 items: widget.optionList
이게 눈에 들어왔고 바로 _controller.items로 변경해봤는데 아쉽게 정답이 아니었다.
이번에는 optionlist에 slelected=true를 넣어보았는데 이번에는 확실하게 잘 되었다. 다만 내가 일일이 넣어줘야하는게 번거로웠다.
마지막 방법은 initState안에서 변수에 값을 넣어주는 방법이다.
controller도 필요없다.
아래 전체코드
import 'package:flutter/material.dart';
import 'package:multi_dropdown/multi_dropdown.dart';
import 'package:y_company/style/color.dart';
import '../../style/themes.dart';
class MultiSelectWidget extends StatefulWidget {
final List<DropdownItem<int>> optionList;
final List<DropdownItem<int>> initialSelection;
final Function(List<int>) onPressed;
const MultiSelectWidget({
super.key,
required this.optionList,
required this.initialSelection,
required this.onPressed,
});
@override
State<MultiSelectWidget> createState() => _MultiSelectWidgetState();
}
class _MultiSelectWidgetState extends State<MultiSelectWidget> {
// final _controller = MultiSelectController<int>();
/// 가공된 items를 저장할 변수
late List<DropdownItem<int>> localItems;
@override
void initState() {
super.initState();
// 1) widget.optionList를 복사 + 선택 항목 처리
localItems = widget.optionList.map((item) {
// 만약 초기 선택값에 들어있는 ID면 selected=true
final isSelected = widget.initialSelection.any(
(sel) => sel.value == item.value,
);
return DropdownItem<int>(
label: item.label,
value: item.value,
selected: isSelected, // 선택 항목이면 true
// disabled: item.disabled,
// 등 필요한 필드를 그대로 복사
);
}).toList();
}
@override
Widget build(BuildContext context) {
return MultiDropdown<int>(
// controller: _controller,
items: localItems,
onSelectionChange: (List<int> selected) {
widget.onPressed(selected);
},
singleSelect: false,
chipDecoration: ChipDecoration(
borderRadius: BorderRadius.circular(16),
wrap: false,
backgroundColor: primaryDark,
labelStyle: Themes.light.textTheme.bodyMedium!.copyWith(
color: white,
),
deleteIcon: Icon(
Icons.remove_circle_outline,
color: white,
size: 18,
),
),
fieldDecoration: FieldDecoration(
borderRadius: 12,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(
color: border,
width: 1,
),
),
),
dropdownItemDecoration: DropdownItemDecoration(
selectedIcon: Icon(
Icons.check_circle,
color: primaryDark,
),
),
// 검색 기능 on/off
searchEnabled: false,
// 유효성 검사 시
validator: (selectedList) {
if (selectedList == null || selectedList.isEmpty) {
return '하나 이상 선택하세요';
}
return null;
},
);
}
}
여기에서 끝낼거지만
기존 코드가 없이 새로 구현한다면 optionList, initialSelection 두개의 리스트를 따로 받지 않고 그냥 하나의 리스트에 selected=true 로 만들어서 넘긴 뒤에 바로 items에 넣어주는게 좋을거같다.