'자식 위젯에서 부모 위젯 데이터 전달'에 해당되는 글 1건

728x90

플러터 팝업창에서 입력한 값을 전달받아 Array 를 업데이트하는 예제이다.

부모 위젯에서 만든 함수를 자식 위젯으로 인자로 넘겨서, 자식 위젯에서 입력한 변수를 받아서 매개변수로 넘기면 ListView가 업데이트되는 코드이다.

import 'package:flutter/material.dart';
 
class LView extends StatefulWidget {
  const LView({Key? key, required this.title}) : super(key: key);
 
  final String title; // 부모 위젯으로부터 전달받은 변수
 
  @override
  State<LView> createState() => _LViewState();
}
 
class _LViewState extends State<LView> {
  var person = ['강감찬''홍길동''이순신''유관순'];
  var clickme = [0000];
 
  addNameArr(name) { // 자식 위젯에서 입력한 값을 전달받아 Array Update
    setState(() {
      person.add(name);
      clickme.add(0);
    });
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
          itemCount: person.length,
          itemBuilder: (c, i) {
            return ListTile(
              leading: Text(clickme[i].toString()),
              title: TextButton(
                child: Text(person[i]),
                onPressed: () => showDialog<String>(
                    context: context,
                    barrierDismissible: false// Dialog를 제외한 다른 화면 터치 x
                    builder: (context) {
                      return DialogUI(
                          Cnt: clickme[i], Name: person[i]); // 변수 넘겨주기
                    }),
              ),
              trailing: ElevatedButton(
                child: Text('좋아요'),
                onPressed: () {
                  setState(() {
                    clickme[i]++;
                  });
                },
              ),
            );
          }),
      floatingActionButton: FloatingActionButton(
        onPressed: () => showDialog(
            context: context,
            builder: (context) {
              return InsertDialogUI(addNameArr: addNameArr);
            }),
        child: const Icon(Icons.add),
      ),
    );
  }
}
 
class DialogUI extends StatelessWidget {
  const DialogUI({Key? key, this.Cnt, this.Name}) : super(key: key);
  final Cnt; // 부모 위젯으로부터 전달받은 변수 등록
  final Name; // 부모 위젯으로부터 전달받은 변수 등록
 
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      // RoundedRectangleBorder - Dialog 화면 모서리 둥글게 조절
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
      backgroundColor: Colors.white,
      //Dialog Main Title
      title: Column(
        children: <Widget>[
          Text("팝업 메시지"),
        ],
      ),
      //
      content: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
            "카운트 횟수 ${Cnt}, 이름 : ${Name}",
          ),
        ],
      ),
      actions: <Widget>[
        ElevatedButton(
          onPressed: () => Navigator.pop(context, 'Cancel'),
          child: const Text('Cancel'),
        ),
        ElevatedButton(
          onPressed: () => Navigator.pop(context, 'OK'),
          child: const Text('OK'),
        ),
      ],
    );
  }
}
 
class InsertDialogUI extends StatelessWidget {
  InsertDialogUI({Key? key, this.addNameArr}) : super(key: key);
  final addNameArr; // 부모 위젯에서 전달받은 변수(함수)
 
  final _textFieldController = TextEditingController();
 
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Item 추가'),
      content: TextField(
        controller: _textFieldController,
        decoration: const InputDecoration(hintText: "성명 입력하세요"),
      ),
      actions: [
        ElevatedButton(
          onPressed: () => Navigator.pop(context, 'Cancel'),
          child: const Text('Cancel'),
          style: ElevatedButton.styleFrom(
            primary: Colors.green,
            onPrimary: Colors.white,
          ),
        ),
        ElevatedButton(
          onPressed: () {
            addNameArr(_textFieldController.text);
            Navigator.pop(context);
          },
          child: const Text('OK'),
          style: ElevatedButton.styleFrom(
            primary: Colors.green,
            onPrimary: Colors.white,
          ),
        ),
      ],
    );
  }
}

 

 

블로그 이미지

Link2Me

,