flutter multi_dropdown package 버전업

namYeJi9q·2025년 1월 3일
0

Flutter

목록 보기
8/8

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에 넣어주는게 좋을거같다.

profile
개발로 먹고 살 예정

0개의 댓글