flutter ReorderableListView

Pyo·2023년 9월 14일
0
post-thumbnail

첫 번째 게시글을 어떤 글을 쓸까 고민을 하던중 올해 초 입사를 하고 처음 업무를 받아 사용했어서 기억에 남는 ReorderableListView 위젯 에 대해 작성해 볼것이다.

ReorderableListView

ReorderableListView 위젯은 ListView 위젯과 비슷하지만, 사용자가 리스트 아이템을 스크롤 가능한 리스트 내에서 재정렬할 수 있는 기능을 제공하는 위젯이다. 이를 통해 리스트 아이템의 순서를 사용자 정의로 변경할 수 있으며, 이 기능은 다양한 앱에서 유용하게 활용될 수 있다.

코드 작성

일반적인 ReorderableListPage 위젯에서 리스트 랜덤의 아이템들을 배치하여 아이템을 추가 , 삭제 할수 있는 기능을 넣어서 간단한 예제 코드를 작성했다.

import 'dart:math';
import 'package:flutter/material.dart';

class ReorderableListPage extends StatefulWidget {
  const ReorderableListPage({super.key});

  @override
  State<ReorderableListPage> createState() => _ReorderableListState();
}

Random randomSeed = Random();

class _ReorderableListState extends State<ReorderableListPage> {
  List<int> numbers = [];

  @override
  void initState() {
    super.initState();
    for (var i = 0; i < 10; i++) {
      numbers.add(randomSeed.nextInt(100) + 1);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            const SizedBox(
              height: 30,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                    onPressed: () {
                      setState(() {
                        // randomNumber = randomSeed.nextInt(100) + 1;
                        numbers.add(randomSeed.nextInt(100) + 1);
                      });
                    },
                    child: const Text('추가')),
              ],
            ),
            Expanded(
                child: ReorderableListView(
                    padding: const EdgeInsets.symmetric(horizontal: 40),
                    children: [
                      for (int index = 0; index < numbers.length; index++)
                        ListTile(
                          key: Key('$index'),
                          title: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                Text('${numbers[index]}'),
                                ElevatedButton(
                                    onPressed: () {
                                      setState(() {
                                        numbers.remove(numbers[index]);
                                      });
                                    },
                                    child: const Text('삭제')),
                              ]),
                          trailing: const Icon(Icons.menu),
                        ),
                    ],
                    onReorder: (int oldIndex, int newIndex) {
                      setState(() {
                        if (oldIndex < newIndex) {
                          newIndex -= 1;
                        }
                        numbers.insert(newIndex, numbers.removeAt(oldIndex));
                      });
                    })),
          ],
        ),
      ),
    );
  }
}

ReorderableListView 위젯은 화면을 그리고 아이템의 순서를 변경하는 데 필요한 두 가지 주요 매개변수를 가지고 있다. 이 위젯을 사용할 때 먼저 children 매개변수를 살다. 이 매개변수는 리스트 아이템을 나타내는 위젯들의 목록인 List을 받는다. 각 아이템은 ListTile 또는 다른 사용자 지정 위젯일 수 있다.

그 다음은 onReorder 콜백 함수입니다. 이 콜백 함수는 아이템을 재정렬할 때 호출된다. 사용자가 아이템을 이동할 때, 이 함수를 사용하여 아이템의 순서를 업데이트한다.

onReorder 함수 내에서는 oldIndex와 newIndex 매개변수를 사용하여 이동하려는 아이템의 이전 위치(oldIndex)와 새 위치(newIndex)를 알 수 있다. 이때, oldIndex에 해당하는 아이템을 리스트에서 제거하고 newIndex 위치에 삽입하여 순서를 변경한다.

그러나 주의할 점은 oldIndex가 newIndex보다 작은 경우에 대한 처리이다. 이 경우, newIndex에서 1을 빼주어야 하는데 , 이유는 아이템을 이동할 때 removeAt 함수를 사용하여 리스트의 길이가 감소하면, newIndex가 리스트 범위를 벗어나게 되기 때문이다. 따라서 마지막 아이템을 이동할 때 에러를 방지하기 위해 newIndex에서 1을 빼주는 것이 필요하다.

마무리

처음 글을 써보았는데 공부한지 오래된 내용이라서 잊고 있던 내용이었는데 글을쓰면서다시 공부 할수 있어서 만족스러웠다. 당시 프로젝트에서는 ReorderViewList 위젯을 사용하지 않고 , ListView 위젯과 Draggable 위젯을 사용하여 Bloc 패턴으로 상태관리를 하여 직접구현하였지만 첫 업무였기에 기억에 많이 남았다. 다음에는 ListView 위젯과 Draggable 위젯을 이용하여 ReorderableListView 위젯을 직접 구현하는 방법에 대한 글을 작성해보려고 한다.

참고

https://api.flutter.dev/flutter/material/ReorderableListView-class.html
https://velog.io/@sharveka_11/Flutter-36.-ReorderableListView

0개의 댓글