Flutter

[Flutter] 자식 위젯이 부모 위젯의 state 사용 2

hminor 2023. 7. 31. 17:21
  • 유저가 입력한 데이터를 변수에 담는 방법
    • controller
      • input 데이터를 담을 변수를 생성 후 TextEditingController() 위젯을 담아주고
        • var inputData = TextEditingController();
      • TextField에 controller: input 데이터 담은 변수 이름 을 작성해주면
        • child: TextField( controller: inputData ,style: TextStyle(fontSize: 30),),
      • 자동으로 변경되는 input 데이터에 대한 value 값이 담겨지게 된다. (이건 좀 편하네)
      • 해당 데이터의 값을 출력하고자 한다면 변수.text를 하면 된다
        • print(변수.text)
    • onChanged()
      • React에서 사용하는 것과 유사
      • onChanged: (value){}
        • 입력 값은 value에 담기게 되고 해당 값을 가지고 변수에 담아주면 된다.

 

숙제

  • 이제 상위 클래스에 있는 배열로 만들어지는 유저 목록을 하위 클래스인 모델에서
     입력한 텍스트를 상위 클래스의 배열에 추가해서 유저 목록을 생성하기
import 'package:flutter/material.dart';

void main() {
  runApp(
      MaterialApp(
        home: MyApp()
      )
  );
}

class MyApp extends StatefulWidget {
  MyApp({super.key});
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  var total = 3;
  var a = 1;
  var name = ['메시', '날강두', '홀란'];
  var cnt = [0, 0, 0];
  var title = 'Contact';

  changeNumber(){
    setState(() {
      total++;
    });
  }

  changeName(value){
    setState(() {
      name.add(value);
    });
  }

  changeCnt(){
    setState(() {
      cnt.add(0);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          showDialog(context: context, builder: (context){
            return Dialog(
              child: Modal(state: title, changeNumber: changeNumber, changeName:changeName, changeCnt:changeCnt)
            );
          });
        },
      ),
      appBar: AppBar(title: Text(total.toString()),),
      body: ListView.builder(
          itemCount: name.length,
          itemBuilder: (c,i){
            return ListTile(
              leading: Text(cnt[i].toString()),
              title: Text(name[i]),
              trailing: TextButton(
                child: Text('좋아요'),
                onPressed: (){
                  setState(() {
                    cnt[i]++;
                  });
                },
              ),
            );
          }
      ),
    );
  }
}

class Modal extends StatelessWidget {
  Modal({super.key, this.state, this.changeNumber, this.changeName, this.changeCnt});
  final state;
  final changeNumber;
  var changeName;
  var changeCnt;
  var inputData = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 400,
      margin: EdgeInsets.fromLTRB(30, 0, 30, 0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            margin: EdgeInsets.all(30),
            child: Text(state, style: TextStyle(fontSize: 40, fontWeight: FontWeight.w900)),
          ),
          Container(
            margin: EdgeInsets.all(30),
            child: TextField( controller: inputData, style: TextStyle(fontSize: 30),),
          ),
          Container(
            margin: EdgeInsets.all(30),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Container(
                  margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
                  child: TextButton(onPressed: (){
                    Navigator.pop(context);
                  }, child: Text('Cencel', style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),)),
                ),
                Container(
                  margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
                  child: TextButton(onPressed: (){
                    changeName(inputData.text.toString());
                    changeCnt();
                  }, child: Text('OK', style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),)),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

 

숙제_ 추가 과제

  • 완료를 누를 시 닫히게 하기
  • 빈칸이면 완료눌러도 추가안되게
  • 이름 옆에 삭제버튼 구현 및 기능 구현
  • 폰 번호 추가(우선은 임시로 010-1234-5678 로 하드코딩해서 넣어주기)
import 'package:flutter/material.dart';

void main() {
  runApp(
      MaterialApp(
        home: MyApp()
      )
  );
}

class MyApp extends StatefulWidget {
  MyApp({super.key});
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  var a = 1;
  var total = 3;
  var person = [['메시', 0, '010-1234-5678'], ['날강두', 0, '010-1234-5678'], ['홀란', 0, '010-1234-5678']];
  // var cnt = [0, 0, 0];
  var title = 'Contact';

  changeNumber(){
    setState(() {
      total++;
    });
  }

  changeState(value){
    setState(() {
      person.add(value);
    });
  }

  deleteState(idx){
    setState(() {
      person.removeAt(idx);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          showDialog(context: context, builder: (context){
            return Dialog(
              child: Modal(state: title, changeNumber: changeNumber, changeState:changeState)
            );
          });
        },
      ),
      appBar: AppBar(title: Text(total.toString()),),
      body: ListView.builder(
          itemCount: person.length,
          itemBuilder: (c,i){
            return ListTile(
              leading: Text(person[i][1].toString()),
              title: Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text(person[i][0].toString()),
                  Text('     '),
                  Text(person[i][2].toString()),
                  Text(' '),
                  TextButton(onPressed: (){
                    deleteState(i);
                  }, child: Text('삭제'))
                ],
              ),
              trailing: TextButton(
                child: Text('좋아요'),
                onPressed: (){
                  setState(() {
                    person[i][1] = (person[i][1] as int) +1;
                  });
                },
              ),
            );
          }
      ),
    );
  }
}

class Modal extends StatelessWidget {
  Modal({super.key, this.state, this.changeNumber, this.changeState});
  final state;
  final changeNumber;
  var changeState;
  var inputData = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 400,
      margin: EdgeInsets.fromLTRB(30, 0, 30, 0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            margin: EdgeInsets.all(30),
            child: Text(state, style: TextStyle(fontSize: 40, fontWeight: FontWeight.w900)),
          ),
          Container(
            margin: EdgeInsets.all(30),
            child: TextField( controller: inputData, style: TextStyle(fontSize: 30),),
          ),
          Container(
            margin: EdgeInsets.all(30),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Container(
                  margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
                  child: TextButton(onPressed: (){
                    Navigator.pop(context);
                  }, child: Text('Cencel', style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),)),
                ),
                Container(
                  margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
                  child: TextButton(onPressed: (){
                    if (inputData.text != ''){
                      changeState([inputData.text.toString(), 0, '010-1234-5678']);
                      Navigator.pop(context);
                    }
                  }, child: Text('OK', style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),)),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}