ABOUT ME

-

  • [ Flutter ] 팝업에서 입력값 리스트에 추가하기
    Application/Flutter 2024. 7. 20. 18:42
    반응형

    팝업에서 금액을 입력하면 바로 리스트에 추가시키는 기능을 구현


    View Setting

    리스트를 관리하기위해 리스트 변수를 선언

    Cost라는 타입을 만들고 Cost타입의 빈 리스트를 선언

    class Cost {
      final int id;
      final String title;
      final String pay;
    
      Cost({
        required this.id,
        required this.title,
        required this.pay,
      });
    }
    
    List<Cost> fixedCost = [];

     

    이후 ExpansionChild에 리스트로 보여주기 위해서

     child: ExpansionTile(
                backgroundColor: Colors.transparent,
                title: Text('Item 1', style: TextStyle(color: textColor)),
                iconColor: textColor,
                onExpansionChanged: (bool expanded) {
                  setState(() {
                    _isExpanded = expanded;
                  });
                },
                children: [
                  Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: ExpansionChildColumn()),
                ],
              ),

     

    ExpansionTile안에 들어갈 내용을 자식 위젯으로 만들어서 사용

    안에서 fixedCost 리스트 변수를 가져와 반복문으로 리스트를 순서대로 보여주도록 설정

    Column ExpansionChildColumn() {
        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].title, fixedCost[i].pay),
              ),
            AddChildList(),
          ],
        );
      }
    
      Row ExpansionChildList(String title, String pay) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              title,
              style: TextStyle(color: textColor),
            ),
            Text(
              formatMoney(pay) + ' 원',
              style: TextStyle(color: textColor),
            ),
          ],
        );
      }

    https://yumedev.tistory.com/20

     

    [ Flutter ] 금액 formatter 설정

    금액을 표시할때 세자리 단위로 , 를 만들기위해 formatter를 만들려고 한다. 이전에 캘린더를 사용할때intl 의존성을 추가했는데 이를 활용하여 formatter를 만들 수 있었다.dependencies: flutter: sdk: flutt

    yumedev.tistory.com

    금액 표시는 formatter 함수를 만들어서 사용

     

    그럼 리스트안에 3개의 값이 존재하면 이런 형태로 리스트를 보여준다.


    Provider Setting

    fixedCost 리스트 값으로 맨 처음 초기화를 해주고

     

    이후 addFixList함수를 이용해 리스트에 값을 추가

    입력한 값을 받아와서 Cost타입의 변수를 세팅 한 후 list에 값을 추가하여 다시 fixedCost에 값을 저장

    class FixSaveProvider extends ChangeNotifier {
      List<Cost> _list = fixedCost;
    
      void addFixList(String value) {
        Cost param = Cost(id: _list.length + 1, title: "test", pay: value);
        _list.add(param);
        fixedCost = _list;
        notifyListeners();
      }
    }

     

    변경되었다는 것을 감지하기위해 이전에 다크테마 변경 설정을 위해 Consumer를 설정했는데

    그 안에 이번에 만든 Provider를 감지시켜주기 위해 Consumer를 추가

     

    class _HomeState extends State<Home> {
      @override
      Widget build(BuildContext context) {
        return Consumer<ThemeProvider>(
          builder: (context, themeProvider, child) {
            return Consumer<FixSaveProvider>(
              builder: (context, fixSaveProvider, child) {
                return Column(
                  children: [
                    // IncomeComponent(),
                    FixedCostComponent(),
                    ViewModeChangeComponent(),
                  ],
                );
              },
            );
          },
        );
      }

     

    기존 main.dart부분에서는 여러개의 provider를 사용하기위해 MultiProvider를 사용하여 provider를 세팅

    @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (context) => ThemeProvider()),
            ChangeNotifierProvider(create: (context) => FixSaveProvider()),
          ],
    반응형

    TextController

    부모의 위젯에 textEditingController를 선언

    그러면 입력한 값이 자동으로 controller에 담기게 된다.

    class _BottomModalState extends State<BottomModal> {
      final TextEditingController _controller = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return Container(
          width: double.infinity,
          height: 250,
          decoration: BoxDecoration(
            color: boxColor,
          ),
          child: Center(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [textField(), SaveChildButton(context)],
          )),
        );
      }

     

    controller를 선언했으면 textField에 controller를 연결해준다.

    Padding textField() {
        return Padding(
          padding: EdgeInsets.all(16.0),
          child: TextField(
            controller: _controller,
            decoration: InputDecoration(
                hintText: '0',
                hintStyle: TextStyle(color: textLightColor),
                filled: true,
                fillColor: buttonColor,
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(8.0),
                  borderSide: BorderSide.none,
                )),
            style: TextStyle(color: textColor),
            keyboardType: TextInputType.number,
            inputFormatters: <TextInputFormatter>[
              FilteringTextInputFormatter.digitsOnly,
            ],
          ),
        );
      }

     

    이후 저장 버튼에서 Provider를 설정하여

    provider에 입력한 값을 전달하고 동시에 팝업창을 닫는다

      Container SaveChildButton(BuildContext context) {
        final fixSaveProvider =
            Provider.of<FixSaveProvider>(context, listen: false);
        return Container(
          margin: const EdgeInsets.fromLTRB(0, 0, 16.0, 0),
          alignment: Alignment.centerRight,
          child: ElevatedButton(
              onPressed: () {
                fixSaveProvider.addFixList(_controller.text);
                Navigator.pop(context);
              },
              style: ElevatedButton.styleFrom(
                  backgroundColor: buttonColor,
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(4)),
                  elevation: 0),
              child: Text(
                '저장',
                style: TextStyle(color: textColor),
              )),
        );
      }

     

    그럼 팝업창에서 입력한 값이 provider를 통해 리스트에 값이 담기고

    이후 consumer가 이를 감지하여 해당 리스트가 변경됨에 따라서 리스트를 다시 불러와 값을 보여준다.

    728x90
    반응형