ABOUT ME

-

  • [ Flutter ] Slidable Custom
    Application/Flutter 2024. 8. 29. 00:36
    반응형

    이전에 Hive를 활용하여 저장 기능을 구현하였기에 이제 수정과 삭제 기능을 구현하기 위해서 Slidable을 활용

    https://pub.dev/packages/flutter_slidable

     

    flutter_slidable | Flutter package

    A Flutter implementation of slidable list item with directional slide actions that can be dismissed.

    pub.dev

    Slidable은 리스트를 옆으로 넘겨 삭제 혹은 버튼을 선택할 수 있도록 해준다.


    Dependencies

    Slidable을 사용하기 위해 yaml파일에 의존성 추가

    dependencies:
      flutter:
        sdk: flutter
         # list Slider
      flutter_slidable: ^3.1.1

    Use

    slidable 에는 startActionPane 과 endActionPane이 존재

    startActionPane은 오른쪽으로 슬라이드 할때 왼쪽에 버튼이 나오고

    endActionPane은 왼쪽으로 슬라이드할때 오른쪽에 버튼이 나온다.

     

    두 action을 동시에 사용할 수 있지만,

    endActionPane을 선택하여 기능을 구현

     

    motion의 경우에는 여러 종류가 있지만 기본 모션인 ScrollMotion을 사용 문서를 보면 더 다양한 motion들이 존재한다.

    extentRatio는 옆에 나오는 버튼이 화면에 어느정도 비율을 차지할 것인지를 나타낸다.

    버튼을 직접 커스텀을 하였기에 비율을 보며 0.25로 측정하여 적용

     

     

      Slidable ExpansionChildList(Cost cost) {
        final double buttonSize = 30.0;
    
        return Slidable(
          endActionPane: ActionPane(
            motion: const ScrollMotion(),
            extentRatio: 0.25,
            children: [
              SizedBox(width: 10.0),
              Container(
                width: buttonSize,
                height: buttonSize,
                child: ElevatedButton(
                  onPressed: () {},
                  style: ElevatedButton.styleFrom(
                      backgroundColor: boxColor,
                      elevation: 0,
                      padding: const EdgeInsets.all(0.0),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(4.0))),
                  child: SvgPicture.asset(
                    'assets/icons/pencil.svg',
                    color: mint,
                    width: buttonSize * 0.6,
                    height: buttonSize * 0.6,
                  ),
                ),
              ),
              SizedBox(width: 5.0),
              Container(
                width: buttonSize,
                height: buttonSize,
                child: ElevatedButton(
                  onPressed: () {},
                  style: ElevatedButton.styleFrom(
                      backgroundColor: boxColor,
                      elevation: 0,
                      padding: const EdgeInsets.all(0.0),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(4.0))),
                  child: SvgPicture.asset(
                    'assets/icons/trash.svg',
                    color: red,
                    width: buttonSize * 0.6,
                    height: buttonSize * 0.6,
                  ),
                ),
              ),
            ],
          ),
          child : ...

     

    children부분이 슬라이드를 했을때 나오는 영역이다

    문서에서는 이런식으로 SlidableAction 버튼이 존재

    이 외로 customSlidableAction이 존재하여 좀 더 커스텀을 진행할 수 있다

    https://pub.dev/documentation/flutter_slidable/latest/flutter_slidable/CustomSlidableAction-class.html

     

    CustomSlidableAction class - flutter_slidable library - Dart API

    CustomSlidableAction class Represents an action of an ActionPane. Properties autoClose → bool Whether the enclosing Slidable will be closed after onPressed occurred. final backgroundColor → Color The background color of this action. final borderRadius

    pub.dev

     

     

    children: const [
          // A SlidableAction can have an icon and/or a label.
          SlidableAction(
            onPressed: doNothing,
            backgroundColor: Color(0xFFFE4A49),
            foregroundColor: Colors.white,
            icon: Icons.delete,
            label: 'Delete',
          ),
          SlidableAction(
            onPressed: doNothing,
            backgroundColor: Color(0xFF21B7CA),
            foregroundColor: Colors.white,
            icon: Icons.share,
            label: 'Share',
          ),
        ],



    하지만 SlidableAction을 사용할경우 svg파일을 사용할 수 없고 또한 너비와 높이를 수정할 수 없어서 직접 button을 넣어서 커스텀

    svg파일의 경우 iconData 타입으로 변환을 할 수 없기에 SlidableAction의 icon에 적용 시킬 수 없다.

    children: [
              SizedBox(width: 10.0),
              Container(
                width: buttonSize,
                height: buttonSize,
                child: ElevatedButton(
                  onPressed: () {},
                  style: ElevatedButton.styleFrom(
                      backgroundColor: boxColor,
                      elevation: 0,
                      padding: const EdgeInsets.all(0.0),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(4.0))),
                  child: SvgPicture.asset(
                    'assets/icons/pencil.svg',
                    color: mint,
                    width: buttonSize * 0.6,
                    height: buttonSize * 0.6,
                  ),
                ),
              ),
              SizedBox(width: 5.0),
              Container(
                width: buttonSize,
                height: buttonSize,
                child: ElevatedButton(
                  onPressed: () {},
                  style: ElevatedButton.styleFrom(
                      backgroundColor: boxColor,
                      elevation: 0,
                      padding: const EdgeInsets.all(0.0),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(4.0))),
                  child: SvgPicture.asset(
                    'assets/icons/trash.svg',
                    color: red,
                    width: buttonSize * 0.6,
                    height: buttonSize * 0.6,
                  ),
                ),
              ),
            ],

     

    이렇게 되면 아래처럼 버튼을 직접 원하는 크기 및 아이콘을 넣어 커스텀을 할 수 있다

     

    마지막 child부분은 리스트 혹은 슬라이드를 할 내용을 만든다.

    child: Container(
            padding: EdgeInsets.fromLTRB(0, 5.0, 0, 5.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  cost.title,
                  style: TextStyle(color: textColor),
                ),
                Text(
                  formatMoney(cost.pay) + ' 원',
                  style: TextStyle(color: textColor),
                ),
              ],
            ),
          ),
        );

     

    각 row마다 Slidable이 적용되야하므로 

    반복문을 활용하여 내용을 생성

      Column ExpansionChildColumn(FixSaveProvider fixSaveProvider) {
        final fixedCost = fixSaveProvider.getFixedCost;
    
        return Column(
          children: [
            for (int i = 0; i < fixedCost.length; i++)
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0.0, 16.0, 16.0),
                child: ExpansionChildList(fixedCost[i]),
              ),
            AddChildList(),
          ],
        );
      }

     

    728x90
    반응형