Flutter - showDialog 사용 방법, 다이얼로그를 출력하여 상호작용하기 (AlertDialog 활용)

반응형

 

Overview

이전에 다이얼로그와 플로팅 액션바를 이용한 메모 앱 만들기를 통해 다이얼로그에 대한 설명을 하였었지만,

이전 포스팅에서는 앱의 기능 구현을 위주로 포스팅하였으나,

다이얼로그의 설명 내용이 너무 부실한 것 같아서 다이얼로그에 대한 설명만을 담은 포스팅을 새롭게 추가하였습니다.

(이전 포스팅 보러 가기)


이번 포스팅에서는 다이얼로그를 출력하는 기능을 구현해봅니다.

showDialog를 이용하여 AlertDialog 위젯을 생성 후,

다이얼로그로 사용자와 상호작용할 수 있는 방법을 설명합니다.

  • 예시) 다이얼로그에서 숫자를 카운팅하는 앱

 

다이얼로그는 자체적으로 상태변환을 하지 않습니다.

다이얼로그에서 업데이트(상태변환)하는 내용은 다음 포스팅에서 다룹니다.


포스팅에서 진행한 프로젝트는 아래의 깃허브 주소에서 다운로드 가능합니다.


showDialog

Dialog, 대화상자라는 의미는 사용자와 상호작용하기 위해 사용되는 창을 의미한다.

같은 의미로 show Dialog는 현재 화면 위에 새로운 대화상자를 표시하는 위젯을 말한다.

특징으로는 호출하는 부모 위젯의 builder와 context를 공유하지 않으며,

다이얼로그 내의 업데이트를 위해서는(상태변환) StatefulBuilder 혹은 StatefulWidget을 이용해야 한다.

 

이번 포스팅에서는 showDialog의 사용 방법을 익히는 것을 목적으로 한다.


showDialog 기본 구문

아래의 구문은 플러터 공식 문서를 참고하여 만든 기본 구문이다.

필수적으로 기재해야하는 파라미터는 context, builder가 있다.

필수 파라미터와 기본적인 옵션 파라미터 몇 개에 대해서만 알아보자.

[필수 파라미터]

  • context
    • 위젯 트리의 현재 위치를 식별하는 데 사용되는 개체
  • builder
    • 일반적으로 위젯을 생성하는 함수를 의미
    • 예를 들어 'AlertDialog'는 builder를 통해 위젯을 생성한다. 

[옵션 파라미터]

  • barrierDismissible
    • 다이얼로그 바깥 화면의 터치를 허용할지를 나타내는 옵션
    • bool 값으로 입력하며 기본값은 true
    • true: 바깥 화면 터치 허용 // false 바깥 화면 터치 허용하지 않음
    • true일 경우, 바깥 화면을 터치하면 해당 다이얼로그가 사라진다.
    • false일 경우, 밖타 화면을 터치해도 다이얼로그가 사라지지 않으며 다이얼로그의 명시된 절차대로 진행하여야만 한다.
  • barrierColor
    • 다이얼로그 바깥 화면의 색상을 설정
    • 기본 색상은 Colors.black54로 살짝 흐린 반투명의 검정색이다.
    • 예를 들어 Colors.red 로 설정할 경우, 다이얼로그 밖 화면은 빨간색으로 변경된다. 
// showDialog 위젯
Future<void> _dialogBuilder() {
    return showDialog<void>(
      context: context,
      builder: (context) {
        // builder 에서 생성할 위젯
        return 반환할 위젯;
      },
    );
}

AlertDialog

  • Material 디자인의 대화 상자이다.
  • 제목이 위에 표시되며 내용 및 수행 내용들이 아래에 표시된다.

<AlertDialog 예시 화면>


AlertDialog 기본 구문

일반적으로 많이 쓰는 파라미터에 대해 알아보자.

  • title
    • 가장 상단의 영역에서 제목의 역할을 할 내용을 의미한다.
    • 위젯을 값으로 하며, 보편적으로 Text 위젯을 많이 사용한다.
  • content
    • 다이얼로그 중간에 보여질 본문의 내용을 의미한다.
    • title 과 같이 위젯을 값으로 하며, 이 또한 보편적으로 Text 위젯을 많이 사용한다.
  • actions
    • 가장 하단의 영역에서 사용자와 상호작용할 수 있도록 정의된 기능을 수행하는 역할을 한다.
    • 리스트 형태의 위젯을 값으로 하며, 보편적으로 확인과 취소를 위한 버튼으로 구성된 경우가 많다.
return AlertDialog(
    title: const Text('AlertDialog 제목'),
    content: Text('AlertDialog 내용'),
    actions: [
      OutlinedButton(
        onPressed: () {
          Navigator.pop(context);
        },
        child: const Text('확인'),
      ),
      OutlinedButton(
        onPressed: () {
          Navigator.pop(context);
        },
        child: const Text('취소'),
      ),
    ],
);

다이얼로그 출력하기 (showDialog + AlertDialog)

이 포스팅에서는 AlertDialog 를 사용해서 다이얼로그를 출력하는 것을 목표로 한다.

커스텀 다이얼로그를 만들려면 Dialog 위젯을 반환하면 된다.


요구 사항

  •  UI
    • 화면에 값을 표시할 텍스트와 버튼으로 구성
  • 기능
    • 버튼 터치 시, 다이얼로그 출력
    • 출력된 다이얼로그의 버튼을 누르면 메인 화면의 값이 1씩 증가
    • 단, 값은 정수형으로 저장한다.

요약하면 버튼을 눌러 다이얼로그가 출력되면,

해당 다이얼로그 내에서 메인 화면의 값을 카운팅하는 기능을 구현한다.


기능 구현 (코드 작성)

  • 카운팅 숫자를 저장하기 위한 변수 선언
// 카운팅 값을 저장하는 변수
int value = 0;

 

  • 다이얼로그를 보여주는 함수 작성 (함수명 : _dialogBuilder)
Future<void> _dialogBuilder(BuildContext context) {
// 현재 화면 위에 보여줄 다이얼로그 생성
return showDialog<void>(
  context: context,
  builder: (context) {
    // 빌더로 AlertDialog 위젯을 생성
    return AlertDialog(
      title: const Text('다이얼로그 제목'),
      content: const Text('다이얼로그 내용'),
      actions: [
        ElevatedButton(
          // 다이얼로그 내의 확인 버튼 터치 시 값 +1
          onPressed: () {
            setState(() => value++);
          },
          child: const Text('확인'),
        ),
        // 다이얼로그 내의 취소 버튼 터치 시 다이얼로그 화면 제거
        OutlinedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('취소'),
        ),
      ],
    );
  },
);
}

 

  • 메인 build
@override
Widget build(BuildContext context) {
return Padding(
  padding: const EdgeInsets.fromLTRB(0, 100, 0, 0),
  child: Center(
      child: Column(
    children: [
      // 카운팅된 값을 표시하는 영역
      Text('값 : ${value.toString()}'),
      ElevatedButton(
        // 버튼 터치 시 다이얼로그 함수 호출
        onPressed: () {
          // 정의한 다이얼로그 함수
          _dialogBuilder(context);
        },
        child: const Text('다이얼로그 출력'),
      ),
    ],
  )),
);
}

전체 소스 코드

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: MainPage(),
        ),
      ),
    ),
  );
}

class MainPage extends StatefulWidget {
  const MainPage({super.key});

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  // 카운팅 값을 저장하는 변수
  int value = 0;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(0, 100, 0, 0),
      child: Center(
          child: Column(
        children: [
          // 카운팅된 값을 표시하는 영역
          Text('값 : ${value.toString()}'),
          ElevatedButton(
            // 버튼 터치 시 다이얼로그 함수 호출
            onPressed: () {
              // 정의한 다이얼로그 함수
              _dialogBuilder(context);
            },
            child: const Text('다이얼로그 출력'),
          ),
        ],
      )),
    );
  }

  Future<void> _dialogBuilder(BuildContext context) {
    // 현재 화면 위에 보여줄 다이얼로그 생성
    return showDialog<void>(
      context: context,
      builder: (context) {
        // 빌더로 AlertDialog 위젯을 생성
        return AlertDialog(
          title: const Text('다이얼로그 제목'),
          content: const Text('다이얼로그 내용'),
          actions: [
            ElevatedButton(
              // 다이얼로그 내의 확인 버튼 터치 시 값 +1
              onPressed: () {
                setState(() => value++);
              },
              child: const Text('확인'),
            ),
            // 다이얼로그 내의 취소 버튼 터치 시 다이얼로그 화면 제거
            OutlinedButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: const Text('취소'),
            ),
          ],
        );
      },
    );
  }
}

참고

반응형