본문 바로가기

Flutter31

Flutter 구글 로그인 Trouble shooting, PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null, null) Flutter 구글 로그인 구현 중 PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null, null) 에러를 만나게 된다면... Flutter로 많은 앱들을 개발하며 구글 로그인도 접해왔지만 가끔 구현 중에 이상하게 로그인이 안되던 이슈들이 생긴 적이 있었다. 그 때마다 어떻게 해결했는지는 정확하게 기억하질 못해서, 얼마 전까지 이유는 모르지만 열심히 구글링한 덕분에 해결했다는 뿌듯함만 남긴 채 기억에서 지워지곤 했었는데, 이번에도 비슷한 상황이 벌어졌고 꼭 정리를 하고 넘어가야겠다고 판단해서 포스팅을 해보기로 한다. 어떤 현상인가? 구글 로그인 버튼을 누르고 아이디 / 패스워드 입력까지 마친.. 2021. 11. 4.
Flutter 동적 링크(Dynamic Link) 및 카카오톡 공유(Link API) 조합하기 Dynamic Link와 Kakao Link API 를 이용하여 특정 게시글에 대해 카카오톡으로 공유하는 실습을 진행해보도록 하겠다. 오랜만의 Flutter 실습 예제에 대한 기록을 남기려고 하는데, 남기는 이유는 정말 오랜만에 내가 구현해보지 않은 기능을 배우는데 꽤 오랜시간 삽질을 하게 돼서, 다음 번에는 이런 삽질을 좀 덜 하고자 잘 정리해 두고자 한다. 해당 기능은 특정 게시글에서 공유하기 등의 버튼을 통해 카카오톡으로 메시지를 전달하는 기능으로 요약해보면 아래와 같은 모습이다. 해당 기능이 동작하기 위해선 아래의 작업들이 필요하다. 최대한 상세히 정리해둘테니 참고가 필요한 분들에게 도움이 되었으면 하는 바람이다. 카카오톡 링크 사용을 위한 설정 (Link API) Firebase 동적 링크 사용.. 2021. 9. 15.
Flutter로 타이머앱 만들기 구현해야 할 것들 - 0.01초 단위로 늘어나는 타이머 - 기록 버튼을 눌렀을 때 저장되는 순간 시간 - 시작/일시정지 버튼 - 시간 초기화 버튼 1. UI 만들기 - 시간을 나타내는 부분은 Text위젯이 필요 (second, millisecond) - 저장되는 순간 시간이 보여질 ListView 위젯 - 시작/일시정지 버튼, 시간초기화 버튼, 기록 버튼 2. 기본 화면 구성 (앱바, 바텀네비게이션바, 플로팅액션버튼) import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @ov.. 2021. 8. 30.
Flutter 이벤트, 애니메이션 위젯 정리 요약 : GestureDetector, InkWell, Hero, AnimatedContainer, SliverAppBar/SliverFillRemaining/SliverList GestureDetector, InkWell - 텍스트나 이미지 등 이벤트효과 없는 위젯을 감싸서 onTap 등의 이벤트를 줄 수 있다. Hero - 화면 전환시 자연스럽게 연결되게 하는 애니메이션 위젯 (이미지 클릭하면 상세화면 보여줄 때 사용) - 두 페이지를 Hero위젯으로 연결 - tag를 동일하게 사용해서 연결시켜줌 class _MyHomePageState extends State { var _selectedTime; @override Widget build(BuildContext context) { return Sca.. 2021. 8. 23.
Flutter 다이얼로그 위젯 정리 사용자의 확인을 요구하거나 팝업메시지 등을 표시해주고 싶을 때 사용하는 다이얼로그 위젯에 대해 정리해보자. 요약 : AlertDialog, DatePicker, TimePicker AlertDialog - title : 제목 영역 - content : 내용 영역 - SingleChildScrollView, ListBody를 이용하면 스크롤 동작 가능 - action 프로퍼티에는 버튼 적용 - Navigator.of(context).pop() : 다이얼로그 닫기 class _MyHomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget... 2021. 8. 23.
Flutter 입력 관련 위젯 글자, 체크박스, 스위치, 라디오, 드롭다운 등 여러가지 입력에 대한 위젯을 정리해보자. 요약 : TextField, CheckBox, Switch, Radio/RidioListTile, DropDownButton, TextEditingController, Form, TextFormField TextField return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column( children: [ Spacer(), TextField(), // 그냥 밑줄 Spacer(), TextField( decoration: InputDecoration( labelText: 'Input Text' // 입력 힌트 ), ), Spacer(), Text.. 2021. 8. 23.
Flutter 크기/위치/정렬 관련 위젯 화면을 구성한 위젯의 크기, 위치, 정렬 등을 할 때 쓰이는 위젯에 대해 알아보자. 요약 : Center, Expanded, SizedBox, Card Center return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Container( color: Colors.blue, width: 200, height: 200 ) ) ); Expanded return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column( children: [ Expanded( flex: 3, // 비율 child: Container( color: Colors.pinkA.. 2021. 8. 23.
Flutter - View, Bar 위젯 Flutter로 앱개발을 하기 위해선 화면에 보여지는 위젯들을 입맛에 맞게 잘 구현할 줄 알아야 한다. 자주 사용되는 위젯을 정리해 보자. 요약 : SingleChildScrollView, ListView, GridView, PageView, AppBar/TabBar/TabBarView, BottomNavigationBar SingleChildScrollView Column 또는 ListBody를 이용해 위젯을 아래로 쭉 나열하다 보면 화면 크기를 넘어갈 때가 있다. 이 때 스크롤이 필요한데, SingleChildScrollView를 사용해보자 class _MyHomePageState extends State { static const TextStyle optionStyle = TextStyle(font.. 2021. 8. 23.
Flutter & Dart 관련 사이트 1. 블로거 게시글 https://medium.com/flutter-korea/flutter-%EC%BD%94%EB%93%9C%EB%9E%A9-%EA%B0%80%EC%9D%B4%EB%93%9C%EB%9D%BC%EC%9D%B8-b0f4854ddbd5 Flutter 코드랩 가이드라인 이 글은 2019년 6월 29일 (토) 진행 예정인 Flutter 코드랩을 위한 가이드라인입니다. 지난 글과 마찬가지로 해당 코드랩에 참여하지 않아도 이 글을 통해 Flutter에 입문하실 수 있습니다. medium.com https://medium.com/flutter-korea/flutter-vscode%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-edbe44a178c5 Flutter, .. 2021. 8. 22.
[Flutter] pub.dev 유용한 패키지 목록 유용한 패키지들 정리 (계속 추가해나갈 예정) 유용한 패키지 공유하자 #1. photo_view #1. photo_view - 사진 확대할 때 유용하게 쓰임 - Flutter를위한 간단한 확대 / 축소 가능한 이미지 / 콘텐츠 위젯. - PhotoView를 사용하면 핀치, 회전 및 드래그와 같은 사용자 제스처로 이미지를 확대 / 축소하고 이동할 수 있습니다. - 또한 컨테이너, 텍스트 또는 SVG와 같은 이미지 대신 모든 위젯을 표시 할 수 있습니다. - 사용하기 매우 간단하지만 PhotoView는 옵션과 컨트롤러를 통해 매우 사용자 정의 할 수 있습니다. 2021. 6. 26.
[Flutter] Docker, php, mariaDB를 이용한 서버구성 및 CRUD 구현 - (2) 이전 시간까지 docker, nginx 등에 대해 간단히 알아보았고 php, mariaDB를 이용해 백엔드를 구성하고 Flutter와 연동해보자. Flutter에서 백엔드 DB의 데이터를 불러와 보여주고 기본적인 CRUD 동작을 실습해보자. 이번 시간에는 실제 Flutter 소스를 구현하고 데이터를 DB와 연동하는 부분을 구현해보도록 하겠다. #1. Flutter 화면 구성 #2. php API 파일 구성 #3. 동작 테스트 #1. Flutter 화면 구성 Flutter 프로젝트를 하나 생성해주자. 기존 docker 폴더와 같은 위치에 생성해보겠다. 나는 현재 docker 폴더를 flutter_api_example 하위에 위치하도록 만들었었다. flutter 프로젝트도 생성시 flutter_api_exa.. 2021. 6. 11.
Flutter 앱에서 Firebase 사용 하기 (iOS 편) Firebase는 고품질 앱을 빠르게 개발하고 비즈니스를 성장시키는 데 도움이 되는 Google의 모바일 플랫폼 Firebase 에서 제공하는 수많은 기능을 통해 사용자의 데이터를 저장하고 분석하며 비즈니스를 성장시킬 수 있다? 잘 이해가 안간다면 우선 뭐든 만들어보고 무엇을 의미했던건지 역추적해보도록 하자. 해당 게시글에서 Firebase 프로젝트를 생성하는 방법에 대해 알아볼 것이다. #1. 구글 로그인 및 Firebase 프로젝트 생성 #2. Flutter 앱 만들기 (Android Studio 기준) #3. Firebase - iOS 플랫폼 추가하기 #1. 구글 로그인 및 Firebase 프로젝트 생성 - Firebase 프로젝트를 생성하기 위해선 일단 본인의 구글 계정으로 로그인이 필요하다. 자.. 2021. 1. 31.
Flutter 앱에서 Firebase 사용 하기 (Android 편) Firebase는 고품질 앱을 빠르게 개발하고 비즈니스를 성장시키는 데 도움이 되는 Google의 모바일 플랫폼 Firebase 에서 제공하는 수많은 기능을 통해 사용자의 데이터를 저장하고 분석하며 비즈니스를 성장시킬 수 있다? 잘 이해가 안간다면 우선 뭐든 만들어보고 무엇을 의미했던건지 역추적해보도록 하자. 해당 게시글에서 Firebase 프로젝트를 생성하는 방법에 대해 알아볼 것이다. #1. 구글 로그인 및 Firebase 프로젝트 생성 #2. Flutter 앱 만들기 (Android Studio 기준) #3. Firebase - Android 플랫폼 추가하기 #1. 구글 로그인 및 Firebase 프로젝트 생성 - Firebase 프로젝트를 생성하기 위해선 일단 본인의 구글 계정으로 로그인이 필요하.. 2021. 1. 25.
Flutter & Firebase - 인스타그램 클론 (5-1) - 프로필 화면 만들기 오늘의 목표 프로필 페이지를 만들어보자. 내 프로필을 보는 경우, 프로필 편집 버튼이 보여야 할 것이며 다른 사용자의 프로필을 보는 경우, 팔로우 상태가 아니라면 팔로우 버튼이 보여야 하고 팔로우 상태라면 언팔로우 버튼이 보여야 할 것이다. #1. 프로필 화면 구성 #2. 프로필 화면 결과 화면 #3. 프로필 수정 화면 #4. 프로필 수정 화면 결과 화면 #1. 프로필 화면 구성 - 기본 화면 구성 중 프로필 상단부 영역 // build method @override Widget build(BuildContext context) { return Scaffold( appBar: header(context, isAppTitle: false, title: 'Profile',), body: ListView( c.. 2020. 9. 3.
Flutter & Firebase - 인스타그램 클론 (4) - 업로드 화면 만들기 오늘의 목표 이미지를 업로드하기 위한 페이지를 만들어보자. 이미지는 카메라 촬영, 갤러리에서 가져오기의 기능으로 가져올 것이다. #1. 업로드 화면 구성 #2. 업로드 화면 #3. 결과 화면 #1. 업로드 화면 구성 - Upload Image 버튼 클릭 - 사진촬영/갤러리에서 가져오기 기능을 위한 다이얼로그 팝업 - 사진 선택 후 게시를 위한 동작 (share버튼 클릭시) #2. 업로드 화면 - 업로드화면 displayUploadScreen() { return Container( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.add_photo_alternate, color: Colors.grey, siz.. 2020. 9. 2.
Flutter & Firebase - 인스타그램 클론 (3) - 사용자 검색화면 만들기 오늘의 목표 사용자를 검색하는 사용자 검색화면(Search Page)을 만들어보자. 검색어 입력시 입력한 검색어와 일치하거나 검색어를 포함하는 사용자 리스트를 보여주게 된다. #1. 검색창 화면 구성 #2. 검색창(상단) 만들기 #3. 검색결과(하단) 만들기 #4. 참고내용 #5. 결과화면 #1. 검색창 화면 구성 - 상단 : appBar로 된 검색창 - 하단 : 검색 결과를 보여줄 ListView @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, appBar: searchPageHeader(), body: futureSearchResults == null ? displayNoSearc.. 2020. 9. 2.
Flutter & Firebase - 인스타그램 클론 (2) - 기본 화면 만들기 (OAuth 구글 로그인) 오늘의 목표 앞서 추가한 기본 화면에 구글 SignIn 버튼을 실제로 동작하도록 구현해보자. #0. 구글 SignIn 관련 variable 설명 #1. 앱 시작시 build 전 initState #2. 구글 SignIn 버튼 클릭시 동작 #0. 구글 SignIn 관련 variable 설명 - GoogleSignIn : 구글 로그인의 기능을 담당할 변수 - GoogleSignInAccount : 구글 로그인시 계정을 담을 변수 - userReference : 로그인시 user정보 db(firestore)에 저장할 때 사용할 변수 - isSignedIn : 앱 시작시 기 로그인여부를 확인할 변수 - DocumentSnapshot : Firestore에서 실시간 데이터를 주고받을 때 사용하는 용도 // var.. 2020. 9. 2.
Flutter & Firebase - 인스타그램 클론 (1) - 기본 화면 만들기 (로그인 페이지) 오늘의 목표 #1. 프로젝트 생성 (시작이 반이다.) #2. firebase 프로젝트 생성 #3. 로그인 화면 만들기 #4. 하단부 bottomNavigator로 각 페이지 연결해주기 #1. 프로젝트 생성 (시작이 반이다.) #2. firebase 프로젝트 생성 - Android 앱 추가 - iOS 앱 추가 #3. 로그인 화면 만들기 - home_page.dart 파일을 생성하고 간단히 구글 버튼을 추가해보자. import 'package:flutter/material.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState ext.. 2020. 8. 31.
Flutter 터치로 사진 확대/축소 시키기 Flutter 터치로 사진 확대/축소 시키기 이번에는 화면 터치를 통해 사진/그림을 확대/축소 시키는 방법에 대해 알아보겠다. Animation 위젯을 응용하여 사용할 것이고 관련 내용을 통해 progress bar 등으로의 활용도 가능하다. 사용법은 매우매우 간단하다. 동작 원리 1. Animation, AnimationController 생성 2. 특정 행동(터치)을 감지하여 행동 발생시 설정한 애니메이션이 동작하도록 수행 1. Animation, AnimationController 생성 Animation _animation; AnimationController _animationController; @override void initState() { // TODO: implement initStat.. 2020. 8. 27.
Flutter trouble shooting - 잘 되던 빌드가 갑자기 안될 때가 있다. 에러문구 D8: Cannot fit requested classes in a single dex file 원인 : 앱 및 앱이 참조하는 라이브러리에서 메서드가 65,536개를 초과하면 앱이 Android 빌드 아키텍처의 제한에 도달했음을 알리는 빌드 오류가 발생합니다. 개발에 실수해서 생긴건 아니고 pjt에 포함된 메소드 개수가 65,536개가 초과되면 발생하는 오류 조치방법 : android/app/build.gradle에 설정 변경해주기 - 쿼리스냅샷을 가져오는데 시간이 걸려 null 오류가 발생하는 경우가 있다. 또는 가져오는동안 값이 바뀌지 않아 최초 초기화값인 0으로 표시되는 경우가 있다. 후자의 경우는 setState를 통해 설정을 바꿔주었는지 확인.. 2020. 7. 5.
Flutter webview widget 이용하기 앱 개발을 하게 되면 개발을 어떤식으로 할지 정해야 할 것이다. 정하는 갈림길에는 네이티브, 하이브리드(웹/앱), 웹뷰 등 크게 3가지로 볼 수 있다. Flutter는 네이티브를 지원(?)한다고 해야하나.. 나도 정확한 개념은 아직 모르지만 우선 웹뷰는 아니다. 웹뷰는 기존의 웹 방식으로 동작하는걸 앱에서 껍데기만 씌워서 껍데기 안에 웹으로 보여지도록 하는 방식이다. 내가 개발 중인 앱 중에 '책 구매하기' 등의 버튼을 클릭하면 인터파크의 책구매 사이트로 이동하도록 구현해야 하는데 이걸 굳이 Dart로 개발하려면 막막한데 웹뷰 라이브러리를 이용하여 나는 껍데기만 만들고 웹뷰로 보여주면 훨씬 수월하게 개발을 할 수가 있다. 아래의 준비과정 및 구현 방법을 통해 Flutter 내에서 웹뷰를 사용할 수 있다... 2020. 6. 27.
안드로이드 앱 구글스토어에 배포하기 1. 앱 서명하기 keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key 잘 생성되었다. 2. 앱으로부터 keystore 참조하기 배포용 앱을 빌드할 때 참조하기 위해 프로젝트의 android/ 폴더에 key.properties 파일을 생성한 후 다음과 같이 작성한다. storePassword= keyPassword= keyAlias=key storeFile= 3. build.gradle android 상단에 붙여넣기 // start of Gradle 서명 구성 def keystoreProperties = new Properties() def keystorePropertiesFile = rootP.. 2020. 6. 8.
Flutter Firebase auth 사용하기 로그인 또는 회원가입시 email / password로 동작하는 과정을 알아보고자 한다. 입력시 validate과정, flutter와 firebase를 이용해서 firebase authenticate 동작하는 과정이 되겠다. 흐름을 파악하고 이해한 후에 코드를 다시 보자. 1. email / password 입력시 validate되는 과정 (email / password를 제대로 입력했는지 검증) email / password 입력하기 : TextFormField TextFormField와 상응하는 formKey 존재 formKey의 currentState (입력상태랄까?) validate() 메소드로 검증하기 → 비어있진 않은지 등의 내가 체크하고자 넣었던 로직 검증이 완료되면 Sign in 버튼 누르.. 2020. 5. 27.
Flutter로 ToDo앱 클라우드DB로 데이터 관리하기 (feat. Firestore) Firestore는 문서기반 구조로 데이터를 저장하며 기존 SQL 등의 문법 없이도 실시간으로 손쉬운 데이터 CRUD(쓰/읽/업/삭)이 가능하다. 저장단위는 문서(document)이다. 문서는 컬렉션(collection)에 저장되며 문서에는 키-값 형태로 다양한 자료(data) 저장이 가능하다. 자료구조 : Collection > Document > Data (key-value) 1. 컬렉션 생성 : 할일 정보를 저장할 컬렉션을 생성. Firestore화면에서 '컬렉션 시작' 클릭 > '컬렉션 ID'에 'todo' 입력 > 다음 클릭 2. 할일 목록 가져오기 (Query) main.dart에 cloud_firestore.dart import 하기 Todo 클래스 수정 import 'package:flut.. 2020. 5. 23.
Flutter로 ToDo앱 클라우드DB로 연결하기 (feat. Firebase) 지난 번 만든 ToDo 앱은 종료를 하게 되면 데이터가 초기화될 것이다. 다음으로 클라우드DB인 Firebase와 연동하여 데이터를 관리해보자. 1. Firebase 연동하기 (android, iOS) 2. Firestore 설정 1. Firebase 연동하기 - firebase.google.com 구글계정 로그인 후 시작하기 버튼 클릭 - 프로젝트 추가 - 프로젝트 이름 작성 후 계속 버튼 클릭 - Google 애널리틱스 체크해제 후 프로젝트 만들기 클릭 - 생성 완료 - 안드로이드 버튼 클릭 - android > app > build.gradle : applicationId 복사 - 앱 등록 경로에 붙여넣기 후 앱 등록 클릭 - 다음 화면에서 google-services.json 받고 android .. 2020. 5. 23.
Flutter로 ToDo앱 만들기 (feat. GitHub) ToDo 앱에서는 클라우드 DB를 활용하는 앱이다. 할일 추가하기, 할일 완료하기, 할일 삭제하기, 할일 추가/완료/삭제시 클라우드DB인 Firestore에서 데이터 관리 Step1. git repository 만들고 연결 Step2. ToDo앱 기본버전 작성 Step1. git repository 만들고 연결 - flutter app 생성 > 프로젝트 열기 > VCS > Import into Version Control > Create Git Repository - flutter_todo_app 선택 - Git init > Yes 클릭 > (다음캡쳐본 보면 알겠지만) 모든 파일들이 빨간 표시로 보임 - flutter_todo_app 우클릭 > Git > Add (Git에 내 프로젝트들 Add 시키자) .. 2020. 5. 22.
Flutter로 비만도 계산기 만들기 키, 몸무게 2개의 숫자값을 입력받아 비만도를 계산하는 어플 1. 입력 화면 2. 결과 화면 3. 값 검증 및 화면 전환 4. 최종 화면 및 소스 1. 입력 화면 키, 몸무게 입력받는 양식을 Form 위젯으로 wrap해준다. 그리고 submit을 누를 때 키, 몸무게값을 검증하기 위해 form의 상태를 얻기위한 key가 필요하다. 키는 GlobalKey타입으로 선언하고 Form 위젯의 key 프로퍼티로 선언하면 상태를 얻을 수 있다. 키, 몸무게 입력필드는 검증 로직을 작성할 수 있는 TextFormField를 사용한다. form key의 currentState.validate()로 Form 입력값에 대한 검증이 가능하다. (아래 소스는 검증부분 미작성) import 'package:flutter/mat.. 2020. 5. 19.
Flutter 자주 쓰이는 생산성 높여주는 단축키 Flutter로 앱개발을 하다보면 Column, Row, Padding 등의 위젯으로 감싸는 경우가 자주 발생한다. 반대로 감싸고 있던 위젯을 제거해야 하는 경우도 있을 것이다. 내가 작성하고 있는 코드의 탭 위치가 맞지 않는 것 같다. 자동으로 정렬할 순 없을까? 이 때 쉽게 처리해주는 단축키에 대해 정리해보자. 1. 위젯을 다른 위젯으로 감싸거나 감싸져 있는 위젯 제거하기 - 감싸고 싶거나 제거하고 싶은 위젯에 커서를 위치하고 Alt + Enter (mac기준 option + enter)를 누른다. 감싸고 싶다면 Wrap with Widget 으로 가능하며 제거하고 싶은 경우 Remove this widget으로 가능하다. 2. 코드 정렬하기 - 안드로이드스튜디오 : 'Code > Reformat C.. 2020. 5. 17.
Flutter 자주 쓰이는 위젯을 이용한 복잡한 UI 그리기 주요 사용 위젯 - BottomNavigationBar : 하단 탭 구성 - AppBar : 상단 제목줄 구성 - Row, Column : 가로, 세로 레이아웃 구성 - GestureDetector : 클릭 이벤트 만들기 위한 위젯 - Opacity : 투명도 - CarouselSlider : 좌우 슬라이드하는 UI 작성을 위한 라이브러리 - Listview : ListTile과 함께 사용하여 스크롤 가능한 리스트를 만드는 위젯 * ListView 안에 ListView 를 넣어야 하는 경우 physics / shrinkWrap 프로퍼티를 지정해줘야 함 Step 1. 전체 틀 잡기 2. BottomNavigationBar를 이용해 하단 탭 만들기 + AppBar 수정해서 상단부 만들기 3. 메인 화면(Ho.. 2020. 5. 17.
Flutter 버튼 관련 위젯 버튼 위젯은 onPressed 프로퍼티를 꼭 추가하여 클릭했을 때 실행될 함수를 반드시 정해줘야 한다. RaisedButton, FlatButton, IconButton, FloatingActionButton return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column( children: [ RaisedButton( // 입체감을 가진 버튼 child: Text('RaisedButton', style: TextStyle(color: Colors.blue)), color: Colors.amber, onPressed: () {} // 클릭시 실행할 영역 ), FlatButton( // 평평한 버튼 child: Text('FlatBut.. 2020. 5. 15.