2024. 8. 10. 15:09ㆍFlutter
최근 활동하고 있는 팀의 MVP가 간략하게 나오게 되어서
혼자 연습도 할 겸 만들어보고 있었는데
이제 기획을 해주신 분들께서 리스트뷰인데
내가 원하는 위치로 순서를 바꿀 수 있는? 리스트 뷰를 생각하고 계신 거 같아서
나도 한 번 만들어보았다!
블로그를 찾아보니 ReorderableListView를 사용하면 된다고 해서
처음 사용을 해보았다!
class _PracticeState extends State<Practice> {
@override
Widget build(BuildContext context) {
return ReorderableListView.builder(
itemBuilder: itemBuilder,
itemCount: itemCount,
onReorder: onReorder
);
}
위의 코드에서 보이는 것처럼 ReorderableListView.builder를 사용하였다
밑의 itemBuilder에선 각 항목에 대한 리스트를 생성하고
itemCount는 반복할 횟수이고
onReorder은 리스트 항목이 드래그되어 순서가 변경될 때 호출되는 콜백 함수이다
이 함수는 드래그가 끝났을 때 리스트 항목의 위치를 변경하는 로직을 포함한다!
우선 아직 파이어베이스를 연결하지 않았기 때문에
아무 데이터를 넣어서 리스트를 만들어준다
List<String> items = ["게임인문학 과제 제출", "사이드 프로젝트 작업하기", "취업역량 개발 스터디"];
이후 이렇게 코드를 작성해준다
itemCount: items.length,
itemCount는 위의 정의해둔 리스트의 길이만큼 구현을 해주고
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex -= 1;
}
final String item = items.removeAt(oldIndex);
items.insert(newIndex, item);
});
},
onReorder은 oldIndex와 newIndex를 받아서
각 리스트간의 위치 이동이 가능하게끔 구현한다
itemBuilder: (context, index) {
return Container(
key: ValueKey(items[index]), // 고유 키 설정
// margin을 padding으로 변경합니다.
padding: EdgeInsets.symmetric(vertical: 4), // 위아래 패딩을 추가하여 간격 유지
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${items[index]}",
style: TextStyle(fontWeight: FontWeight.bold),
),
Container(
margin: EdgeInsets.fromLTRB(0, 5, 0, 0),
width: 35,
height: 20,
decoration: BoxDecoration(
color: Colors.grey.shade400,
borderRadius: BorderRadius.circular(10),
),
child: Align(
alignment: Alignment.center,
child: Text(
"집중",
style: TextStyle(
fontSize: 10,
color: Colors.grey.shade700,
),
),
),
)
],
),
),
Container(
child: IconButton(
onPressed: () {},
icon: Icon(Icons.drag_handle),
),
),
],
),
),
);
},
마지막으로 itemBuilder에는 내가 해당 리스트에 넣어야할 내용들을 넣어줘야한다
여기서 중요한 것은
key: ValueKey(items[index]), // 고유 키 설정
고유한 키값을 설정해줘야한다
이 부분을 구현하지 않으면 오류가 발생한다
전체코드는 이렇게 된다
class TodayTodoList extends StatefulWidget {
const TodayTodoList({super.key});
@override
State<TodayTodoList> createState() => _TodayTodoListState();
}
class _TodayTodoListState extends State<TodayTodoList> {
List<String> items = ["게임인문학 과제 제출", "사이드 프로젝트 작업하기", "취업역량 개발 스터디"];
@override
Widget build(BuildContext context) {
return Container(
height: 300,
child: ReorderableListView.builder(
itemCount: items.length,
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex -= 1;
}
final String item = items.removeAt(oldIndex);
items.insert(newIndex, item);
});
},
itemBuilder: (context, index) {
return Container(
key: ValueKey(items[index]), // 고유 키 설정
// margin을 padding으로 변경합니다.
padding: EdgeInsets.symmetric(vertical: 4), // 위아래 패딩을 추가하여 간격 유지
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${items[index]}",
style: TextStyle(fontWeight: FontWeight.bold),
),
Container(
margin: EdgeInsets.fromLTRB(0, 5, 0, 0),
width: 35,
height: 20,
decoration: BoxDecoration(
color: Colors.grey.shade400,
borderRadius: BorderRadius.circular(10),
),
child: Align(
alignment: Alignment.center,
child: Text(
"집중",
style: TextStyle(
fontSize: 10,
color: Colors.grey.shade700,
),
),
),
)
],
),
),
Container(
child: IconButton(
onPressed: () {},
icon: Icon(Icons.drag_handle),
),
),
],
),
),
);
},
),
);
}
}
이렇게 만들어주고 사용은 이렇게 해주었다
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("오늘 할 일", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),),
Text("우선순위 파악이 가능하다면 순서대로 정리해보세요", style: TextStyle(fontSize: 12, color: Colors.grey.shade800),),
SizedBox(height: 10,),
TodayTodoList()
],
),
그럼 진짜 마지막으로 어떻게 구현이 되었는지 확인해보자
'Flutter' 카테고리의 다른 글
Flutter Firebase 데이터 update (데이터 수정) (3) | 2024.11.01 |
---|---|
Flutter Firebase 저장(Riverpod 활용) (8) | 2024.10.27 |
[flutter] CupertinoDatePicker를 활용하여 시간 선택 (1) | 2024.09.11 |
Timer를 활용하여 타이머 만들기(Flutter) (0) | 2024.08.15 |
Flutter build 오류 해결,, (0) | 2024.07.26 |