seong
중복 선택 가능한 Dropdown Button 만들기 본문
관심사 선택에 Dropdown Button 으로 구현할 생각이다.
pub.dev에 있는 라이브러리를 사용.
https://pub.dev/packages/dropdown_button2
의존성을 추가해 주고 시작
동작 원리
DropDown버튼은 선택된 상태 값으로 rebuild해서 보여주기 때문에 Stateful위젯으로 만든다.
1. 아이템을 보여줄 리스트, 선택 아이템을 담아줄 리스트를 선언
2. 버튼을 클릭
3. List 중 항목 선택
4. 선택된 항목들을 바탕으로 update를 한다.
5. update된 리스트를 rebuild를 해서 사용자에게 보여준다.
전체 코드
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "DropDownButton Test",
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
State<HomePage> createState() => _HomePage();
}
class _HomePage extends State<HomePage> {
final List<String> items = [
'취미1',
'취미2',
'취미3',
'취미4',
];
List<String> selectedItems = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2(
isExpanded: true,
hint: Align(
alignment: AlignmentDirectional.center,
child: Text(
'취미를 선택해 주세요.',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).hintColor,
),
),
),
items: items.map((item) {
// 아이템의 타입은 map 타입
return DropdownMenuItem<String>(
value: item,
enabled: false,
child: StatefulBuilder(
// 체크 박스의 상태 값은 stateful로 상태값을 확인
builder: (context, menuSetState) {
final _isSelected = selectedItems.contains(item);
return InkWell(
// InkWell - 버튼화
onTap: () {
// 클릭 됬으면 리스트에 add 아니면 remote
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
setState(() {}); // 버튼의 상태를 rebuild
menuSetState(() {}); //버튼의 상태를 update
},
child: Container(
height: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
_isSelected
? const Icon(Icons.check_box_outlined)
: const Icon(Icons.check_box_outline_blank),
const SizedBox(width: 16),
Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
],
),
),
);
},
),
);
}).toList(),
// 선택한 항목이 있다면 선택 항목들을 보여줌.
value: selectedItems.isEmpty ? null : selectedItems.last,
onChanged: (value) {},
buttonHeight: 40,
buttonWidth: 140,
itemHeight: 40,
itemPadding: EdgeInsets.zero,
selectedItemBuilder: (context) {
return items.map(
(item) {
return Container(
alignment: AlignmentDirectional.center,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
selectedItems.join(', '),
style: const TextStyle(
fontSize: 14,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
);
},
).toList();
},
),
),
),
);
}
}
'Flutter > 중계 플랫폼 프로젝트' 카테고리의 다른 글
4. login_division_page (0) | 2022.11.29 |
---|---|
3. LoginPage (0) | 2022.11.29 |
2. 회원가입 분기 페이지 (0) | 2022.11.29 |
1. 내 정보 페이지(로그아웃) (0) | 2022.11.28 |
Flutter - Text overflow 텍스트 길이가 길어지면 ...으로 처리 하기 (0) | 2022.11.26 |