Develop/Flutter

[Flutter]10 Dialog / context란?

dawonny 2022. 2. 17. 03:19
728x90
반응형

ref : 코딩 애플[Flutter로 만드는 iOS, Android 앱] 강의


Dialog 가 뜨도록 해보자

body: Dialog(child: Text('요기요!'))

버튼을 눌렀을 때에 Dialog 가 뜨도록 하려면 onPressed 함수 안에 써주면되는데

showDialog를 쓰면 된다.

showDialog안에는 contextbuilder 가 들어가야한다.

여기까지하면 버튼을 눌러도 아무것도 일어나지 않음

 

일단 첫 페이지는 보통 Scaffold( ) 부터 시작한다.

해결책은 MaterialApp 을 MyApp이라는 커스텀 위젯 바깥으로 보내는 것.

위에 void main() 함수 안에서 MyApp() 을 MaterialApp 으로 감싸주었다.

그럼 버튼을 눌렀을 때 Dialog가 뜨는 동작이 잘된다.

왜 MaterialApp 을 밖으로 빼야할까?

context 가 일단 뭘까

커스텀 위젯을 만들때 context가 자동으로 생성이 될거다.

context  == 부모 위젯의 정보를 담고있는 변수

 

앞으로 쓸 함수들 중에 

showDialog()

Scaffold.of()

Navigator.pop()

Theme.of()

등이 있는데 이 함수들은 안에 context 가 들어가야한다

근데 그 중에서도 MaterialApp 부모가 들어가 있는 context 를 입력해야 잘 동작하는 함수다.

그래서 MaterialApp을 제일 밖으로 빼준 거다.


context 를 생성해주는 방법도 있다

floatingActionButton 을 Builder 로 Wrap 해보자

 

Builder라는 위젯은 무슨 역할을 할까?

중간에 context 을 만들 수 있다.

예를 들어 저기있는 context 에는 Scaffold, MaterialApp 등의 정보가 들어가 있겠다.


실습 : Dialog 안에 텍스트 입력란이랑 버튼 2개(Cancel , OK) 만들기
        Cancel 버튼 눌렀을 때에는 Dialog가 닫히게도 해보자

 

다음은 구글링해보면서 짜본 코드다.

일단 원하는대로 구현이되었다!

 

입력란은 TextField() 를 썼고

다이얼로그의 content 에는 SingleChildScrollView 라는 걸 어떤분이 쓰셨길래 나도 써봤다

버튼은 FlatButton 이라는걸 써봤는데

Navigator.of(context)pop(); 이부분이 다이얼로그 창을 닫게해주는 역할을 하지 않을까 싶다.

 

import 'package:flutter/material.dart';

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



class MyApp extends StatefulWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var like = [0,0,0];
  var name = ['해리', '론', '헤르미온느'];
  @override
  Widget build(BuildContext context) {

    return Scaffold(
          floatingActionButton: FloatingActionButton(
            onPressed: (){
              showDialog(context: context, builder: (context){
                return AlertDialog(
                  title: Text('Contact'),
                  content: SingleChildScrollView(
                    child: ListBody(
                      children: [
                        TextField()
                      ],
                    ),
                  ),
                  actions: [
                    FlatButton(onPressed: (){
                      Navigator.of(context).pop();
                    }, child: Text('Cancel')),
                    FlatButton(onPressed: (){
                      Navigator.of(context).pop();
                    }, child: Text('OK')),
                  ],
                );
              });
            },
          ),
            appBar: AppBar(),
            bottomNavigationBar: BottomAppBar(),
            body: ListView.builder(
                itemCount: 3,
                itemBuilder: (c, i){
                  return ListTile(
                    leading: Icon(Icons.account_box),
                    title: Text(name[i])
                  );
                },
            )
            );


  }
}

728x90
반응형