티스토리 뷰
안녕하세요. 오틸라 입니다.
There should be exactly one item with [DropdownButton]'s value: Instance of 'KeyValueData'.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
flutter에서 dropdownbutton, radiobutton, checkbox 등등 생성할때
기본코드는 text값 하나로 처리합니다.
dropdownbutton으로 예를 들면,
기본코드가
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? value) {
// This is called when the user selects an item.
setState(() {
dropdownValue = value!;
});
},
items: list.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
이런식입니다.
바인딩할때 List<String> 형태로 하고, 값 비교는 String 하나로만 합니다.
그런데 작업을 하다보면, key, value값으로 보여지는 텍스트와, 가져갈 값이랑 별도로 운영해야될때가 많거든요.
그래서 이걸 class로 작업하고, 클래스로 dropdownbutton을 구성하면,
class KeyValueData {
final String key;
final String value;
KeyValueData(this.key, this.value);
}
이런 클래스를 하나 구현하고,
DropdownButton<KeyValueData>(
value: _selectedOption_sell_type.key.isNotEmpty ? _selectedOption_sell_type : null,
hint: Text('판매유형을 선택하세요.'), // Optional initial hint text
onChanged: (KeyValueData? newValue) {
setState(() {
_selectedOption_sell_type = newValue!;
widget.product_data.product_sell_type = newValue.key;
});
},
items: sell_type_list.map((data) {
return new DropdownMenuItem<KeyValueData>(
value: data,
child: new Text(
data.value,
style: new TextStyle(color: Colors.black),
),
);
}).toList(),
)
클래스로 key, value를 따로따로 처리합니다.
그런데 문제는 default값을 선택해줄때
클래스로 비교를 해주는데,
이런 에러가 발생한다는거죠.
이 원인은
바인딩한 KeyValueData 클래스(A)와, default로 넣어준 KeyValueData(B)클래스가 값이 완전히 동일한데도 불구하고,
A == B 를 체크해보면,
false로 나온다는거죠.
객체를 생성하면서 인스턴스값까지 비교를 하니, 다르다고 판단하는 겁니다.
우리는 여기서 클래스가 같고, 그중에서 key값만 같다면 그냥 같은걸로 처리해라라고 추가를 해주면 됩니다.
class KeyValueData {
final String key;
final String value;
KeyValueData(this.key, this.value);
@override
bool operator == (Object other) {
if(other is KeyValueData && other.key == key)
return true;
else
return false;
}
}
operator를 오버라이드 하고,
아까 얘기한, KeyValueData라는 클래스가 같고, 그 클래스값중에 key가 같으면 return true (같은거다)
라고 조건을 재정의 해주면 됩니다.
좀더 간단하게는
class KeyValueData {
final String key;
final String value;
KeyValueData(this.key, this.value);
@override
bool operator == (Object other) => other is KeyValueData && other.key == key;
}
요렇게 적어도 됩니다.
그러면, 이제 클래스끼리 A == B를 비교할때 안에 들어있는 key값이 같으면 통과 됩니다.
이상 오틸라였습니다.
건강하세요~