묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
GoRouter PushAndRemoveUntil 관련
안녕하세요,프로젝트에서 GoRouter를 사용해서 페이지들을 구현하고 있는데요,GoRouter에서는 Navigator.PushAndRemoveUntil에 해당하는 함수가 없을까요?없다면 비슷하게 구현할 수 있는 방법이 있을까요?감사합니다.
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
final 구문의 용법이 궁금합니다.
안녕하세요, 알찬 강의 잘 보고 있습니다. 이번 강의 중 질문 사항이 생겨 여쭤봅니다. final newBlackPink = blackPink.map((x){return '블랙핑크 $x';});이 구문에서, final 과 newBlackPink 사이에 변수 타입(이 경우는 Iterable)에 대한 선언이 있어야하는 것 아닌가? 생각했는데 안 써도 정의가 잘 되더라구요. final을 선언한 이상 변수의 값이 변경되지 않기 때문일까요? 그리고 이런 식으로 Iterable(Set, List 등도) 은 final 로 선언하는 것이 일반적인 용법인지 궁금합니다. 감사합니다.
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
Hive, Riverpop 제너레이터 호환성 문제
안녕하세요 선생님 지난번 날씨앱에서 질문 드리고 중급강의 GoRouter 까지 무지성으로 따라가고있는 수강생입니다.중급 캐시강의를 보다가 문득 든 생각이서버에서 받아온 데이터를 Hive를 사용해서 기기에 저장을 하고 휴대폰 DB에 저장된 리스트들을 Hive에 데이터가 있다면 hive에서 읽고 없다면 새로받아오는 형식으로 Riverpod을 사용해 관리하면 어떨까? 싶은 생각이 들었습니다. 이유는 서버에서 restAPI를 통해 받아온 값들은 메모리에 저장되어있으니 앱을 껏다 키거나 메모리가 초기화되면 캐쉬가 날아가는 것이 아닌가? 라는 생각이 들어서였구요(리스트나 자료들을 휴대폰 db에 저장 해놓고 꺼내쓴다면 재요청횟수가 줄어들어 비용절감이 되지 않을까? 싶은 생각) 그래서 당연히 생각만 가지고 있지 아직은 아무것도 할줄 모르지만 일단Hive와 Riverpod을 동시에 설치는 해보자는 생각에 인스톨 해봤는데요문제는 hive_generator의 버전은 analyzer 5.0과 호환되고 riverpop_generator와 json_serializable 제너레이터들은 analyzer 6.0과 호환되어 한프로젝트에 동시설치가 불가능 한 것 같습니다.analyzer6.0을 사용하는 다른 제너레이터들의 버전을 낮춰봐도 더 복잡하고 많은 에러가 뜨는데요. 1)그래서 캐쉬를 hive로 사용하는게 어떨까? 라는 생각이 맞는 생각인지? (예를들면 riverpod의 캐쉬를 사용하면 되는데 궂이 db를 캐쉬로 왜 사용하는가?)2)유용한 생각이라면 analyzer버전 호환문제를 해결해서 동시에 사용할 수 있는 방법이 있는지?3)동시 설치가 안된다면 hive외 대안이 있거나 sqflite 같은 다른sql이 대안이 되는지? (hive를 캐쉬 대용으로 사용하려고한것은 hive의 빠른속도 때문인데, sqflite를 사용하게되면 궂이 물리적인 db캐쉬가 유효/유용 한건지?) 에 대한 의문이 들었습니다.이런생각을 하는 이유는, 나중에 혼자 앱을 만들게 된다면 서버를 사용하는 것보다 파이어베이스 같은 클라우드 플랫폼을 사용하지 않을까 싶은 생각에서 트래픽을 줄일 수 있는 방법이 궁금해서 였습니다.아직 멋모르고 강의 열심히 따라가는 중이라 급한내용은 아니니 시간 편하실때 천천히 답변주시면 감사하겠습니다.
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
안녕하세요 선생님! 중급강의 적용에 있어 질문드립니다!
안녕하세요!! 코드팩토리님 초급, 중급 강의를 완강한후 인터뷰 매칭 서비스 앱을 개발해보고자하는 학생입니다. 다름이아니라, 앱 설계를 하다 보니 하나의 인터뷰에 인터뷰의뢰 테이블, 인터뷰의뢰채널테이블,인터뷰참여테이블 등 이들간의 관계를 표현하고 각 인터뷰 건에 대한 pagination 적용도 해야하는데, 이 각각의 테이블을 중급강의에서 배운 것들을 model, repository,provider,view 폴더로 나누어 그대로 적용해보고자 하는데 이렇게 하는게 맞을지 갈피가 안잡혀서 질문남기겠습니다. 제가 아직 프로그래밍 경험이 부족해서ㅠㅠ 질문이 다소 추상적으로 느껴졌다면 죄송합니다.
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
'circle' 부분에서 질문
안녕하세요._CustomGoogleMap에서 circle를 전달 받을때circles: Set.from([circle],)이런식으로 Set을 하셨는데, 따로 이렇게 하신 이유가 있을까요? {circle} 이렇게 하는게 더 낫지 않나 싶어서요. 감사합니다
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
섹션 21. 캘린더 스케쥴러 오류 문의드립니다.
색상 상태관리 부분을 듣고 있습니다. 똑 같이 따라했는데요. 아래 내용과 같이 FutureBuilder를 사용하여 똑같이 따라 했는데도 불구하고 null이 리턴되어 오류가 납니다. future: GetIt.I<LocalDatabase>().getCategoryColors() 에서 강사님 강의에서는 데이터를 가지고 오는데, 제가 만든 코드에서는 null이 리턴되네요. 혹시 몰라 main.dart에서 GetIt.I<LocalDatabase>().getCategoryColors() 를 실행해 보고, 결과를 보면 정상적인 데이터가 들어옵니다.뭐가 문제일까요?main.dartimport 'package:calendar_schedule_exam/database/drift_database.dart'; import 'package:calendar_schedule_exam/screen/home_screen.dart'; import 'package:drift/drift.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:intl/date_symbol_data_local.dart'; const DEFAULT_COLORS = [ // 빨강 'F44336', // 주황 'FF9800', // 노랑 'FFEB3B', // 초록 'FCAF50', // 파랑 '2196F3', // 남 '3F51B5', // 보라 '9C27B0', ]; void main() async { WidgetsFlutterBinding.ensureInitialized(); await initializeDateFormatting(); final database = LocalDatabase(); GetIt.I.registerSingleton<LocalDatabase>(database); final result = GetIt.I<LocalDatabase>().getCategoryColors(); final colors = await database.getCategoryColors(); if (colors.isEmpty) { for (String hexCode in DEFAULT_COLORS) { await database.createCategoryColor( CategoryColorsCompanion( hexCode: Value(hexCode), ), ); } } runApp(MaterialApp( theme: ThemeData( fontFamily: 'NotoSans', ), home: HomeScreen(), )); } schedule_bottom_sheet.dartimport 'package:calendar_schedule_exam/component/custom_text_field.dart'; import 'package:calendar_schedule_exam/const/colors.dart'; import 'package:calendar_schedule_exam/database/drift_database.dart'; import 'package:calendar_schedule_exam/model/category_color.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; class ScheduleBottomSheet extends StatefulWidget { const ScheduleBottomSheet({super.key}); @override State<ScheduleBottomSheet> createState() => _ScheduleBottomSheetState(); } class _ScheduleBottomSheetState extends State<ScheduleBottomSheet> { final GlobalKey<FormState> formKey = GlobalKey(); int? startTime; int? endTime; String? content; int? selectedColorId; @override Widget build(BuildContext context) { final bottomInset = MediaQuery.of(context).viewInsets.bottom; return SafeArea( bottom: true, child: GestureDetector( onTap: () => FocusScope.of(context).requestFocus(FocusNode()), child: Container( height: MediaQuery.of(context).size.height / 2 + bottomInset, color: Colors.white, child: Padding( padding: EdgeInsets.only(bottom: bottomInset), child: Padding( padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 16.0), child: Form( key: formKey, autovalidateMode: AutovalidateMode.always, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _Time( onStartSaved: (newValue) { startTime = int.parse(newValue!); }, onEndSaved: (newValue) { endTime = int.parse(newValue!); }, ), SizedBox(height: 16.0), _Content( onSaved: (newValue) { content = newValue; }, ), SizedBox(height: 16.0), FutureBuilder<List<CategoryColor>>( future: GetIt.I<LocalDatabase>().getCategoryColors(), builder: (context, snapshot) { print(snapshot.data); if (snapshot.hasData && selectedColorId == null && snapshot.data!.isNotEmpty) { selectedColorId = snapshot.data![0].id; } return _ColorPicker( colors: snapshot.hasData ? snapshot.data! : [], selectColorId: selectedColorId!, ); }), SizedBox(height: 16.0), _SaveButton( onPressed: onSavePressed, ), ], ), ), ), ), ), ), ); } void onSavePressed() { if (formKey.currentState == null) { return; } if (formKey.currentState!.validate()) { formKey.currentState!.save(); } else { print('에러가 있습니다.'); } } } class _Time extends StatelessWidget { final FormFieldSetter<String> onStartSaved; final FormFieldSetter<String> onEndSaved; const _Time( {super.key, required this.onStartSaved, required this.onEndSaved}); @override Widget build(BuildContext context) { return Row( children: [ Expanded( child: CustomTextField( label: '시작 시간', isTime: true, onSaved: onStartSaved, )), SizedBox(width: 16.0), Expanded( child: CustomTextField( label: '마감 시간', isTime: true, onSaved: onEndSaved, ), ), ], ); } } class _Content extends StatelessWidget { final FormFieldSetter<String> onSaved; const _Content({super.key, required this.onSaved}); @override Widget build(BuildContext context) { return Expanded( child: CustomTextField( label: '내용', isTime: false, onSaved: onSaved, ), ); } } class _ColorPicker extends StatelessWidget { final List<CategoryColor> colors; final int selectColorId; const _ColorPicker( {super.key, required this.colors, required this.selectColorId}); @override Widget build(BuildContext context) { return Wrap( spacing: 8.0, runSpacing: 10.0, children: colors.map((e) => rendColor(e, selectColorId == e.id)).toList(), ); } Widget rendColor(CategoryColor color, bool isSelected) { return Container( decoration: BoxDecoration( shape: BoxShape.circle, color: Color(int.parse('FF${color.hexCode}', radix: 16)), border: isSelected ? Border.all(color: Colors.black, width: 1.0) : null, ), height: 32, width: 32); } } class _SaveButton extends StatelessWidget { final VoidCallback onPressed; const _SaveButton({super.key, required this.onPressed}); @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: PRIMARY_COLOR, ), onPressed: onPressed, child: Text('Save'), ), ); } } drift_database.dartimport 'dart:io'; import 'package:calendar_schedule_exam/model/category_color.dart'; import 'package:calendar_schedule_exam/model/schedule.dart'; import 'package:drift/drift.dart'; import 'package:drift/native.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; part 'drift_database.g.dart'; @DriftDatabase( tables: [ Schedules, CategoryColors, ], ) class LocalDatabase extends _$LocalDatabase { LocalDatabase() : super(_openConnection()); // insert schedules Future<int> createSchedule(SchedulesCompanion data) => into(schedules).insert(data); // insert categoryColors Future<int> createCategoryColor(CategoryColorsCompanion data) => into(categoryColors).insert(data); // select all categoryColors Future<List<CategoryColor>> getCategoryColors() => select(categoryColors).get(); @override // TODO: implement schemaVersion int get schemaVersion => 1; } LazyDatabase _openConnection() { return LazyDatabase(() async { final dbFolder = await getApplicationDocumentsDirectory(); final file = File(p.join(dbFolder.path, 'db.sqlite')); return NativeDatabase(file); }); }오류내용Launching lib/main.dart on iPhone 14 Pro Max in debug mode... Running Xcode build... Xcode build done. 7.8s [VERBOSE-2:FlutterDarwinContextMetalImpeller.mm(35)] Using the Impeller rendering backend. Debug service listening on ws://127.0.0.1:61505/HeTRp4ZQphA=/ws Syncing files to device iPhone 14 Pro Max... flutter: null ======== Exception caught by widgets library ======================================================= The following _TypeError was thrown building FutureBuilder<List<CategoryColor>>(dirty, state: _FutureBuilderState<List<CategoryColor>>#41541): Null check operator used on a null value The relevant error-causing widget was: FutureBuilder<List<CategoryColor>> FutureBuilder:file:///Users/choiwooin/dev/flutterProject/calendar_schedule_exam/lib/component/schedule_bottom_sheet.dart:57:21 When the exception was thrown, this was the stack: #0 _ScheduleBottomSheetState.build.<anonymous closure> (package:calendar_schedule_exam/component/schedule_bottom_sheet.dart:68:59) #1 _FutureBuilderState.build (package:flutter/src/widgets/async.dart:612:55) #2 StatefulElement.build (package:flutter/src/widgets/framework.dart:5198:27) #3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5086:15) #4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5251:11) #5 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7) #6 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5068:5) #7 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5242:11)
-
해결됨[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
섹션18 영상통화 HomeScreen설계 중 에러
Error: unable to locate asset entry in pubspec.yaml: "asset/NotoSansKR-Black.otf".Target debug_android_application failed: Exception: Failed to bundle asset files.FAILURE: Build failed with an exception.* Where:Script 'C:\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 1201* What went wrong:Execution failed for task ':app:compileFlutterBuildDebug'.> Process 'command 'C:\flutter\bin\flutter.bat'' finished with non-zero exit value 1* Try:> Run with --stacktrace option to get the stack trace.> Run with --info or --debug option to get more log output.> Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 12sException: Gradle task assembleDebug failed with exit code 1
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
asset폴더 통채로 옮기는건 맥에서만 가능한 기능인가요
asset폴더 통채로 옮기는건 맥에서만 가능한 기능인가요?windows는 직접 폴더 만들어서 넣어야 합니까
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
BoxDecoration 코드 정리 관련하여 질문있습니다
BoxDecoration 부분을 Row위젯과 달리 함수가 가져오는 식으로 정리해주셨는데 BoxDecroation도 위젯아닌가요? 어째서 stless를 쓰지않고 함수가 가져오는 식으로 정리한건지 궁금합니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
AppBar 질문
아래 스크린샷처럼 appbar 중앙 정렬이 안되는데몇번을 돌려봐도 강사님과 같은 코드입니다.어떤 옵션이 추가 되어야 할까요?? - 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.코드팩토리 디스코드https://bit.ly/3HzRzUMFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다!
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
이미지가 에뮬레이터에서 보이지 않는 문제
에뮬레이터에서 이미지를 불러오려고 하면 Unable to load asset이 뜨면서 보이지 않습니다!web으로는 'images/logo.png' 경로로 주면 뜨는데 에뮬레이터는 둘 다 안됩니다. pubspec.yaml 파일에이렇게 넣어주었습니다.폴더는 이렇게 설정했습니다!
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
플러터 코드푸쉬
좋은 강의 잘 수강했습니다!플러터를 처음 시작할 때 장단점에 대한 부분에서 코드푸쉬와 앱 업데이트 관련 부분이 플러터의 약점이라고 들었는데, 앱 내부에 조금의 변화라도 있으려면 마켓 승인을 다시 받아야 한다는 뜻인가요?작은 예시로, 배달의 민족 앱을 플러터로 제작하고, 새로운 가게들을 추가하려면, 그 때 마다 외부 데이터베이스와의 연동으로 해결할 수 있는 문제인지, 아니면 마켓에 일일이 승인을 받아야 하는건가요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
안녕하세요 선생님
앱을 시작할 때, splash 스크린을 보여주고, 유저의 정보에 따라 redirect하려합니다. 그런 기대로 지금 현재 코드를 짰는데, 기대한것과 달리 splash 스크린이 아예 띄워지지 않고 곧바로 redirect 됩니다. 혹시 제가 원했던 것처럼 splash 스크린을 단 1초간이라도 보여준 다음 유저 정보에 따라 redirect 하는 방법이나 현재문제의 원인을 알 수 있을까요? 참고로 go router의 버전은 v8입니다.
-
미해결Flutter + Firebase로 넷플릭스 UI 클론 코딩하기 [무작정 플러터]
firebase 설치이후 디버깅하면 아래와 같은 에러가 발생하는데 알려주실분 계실까요?
code build done. 540.2sFailed to build iOS appError (Xcode): redefinition of module 'Firebase'/Users/hoon/development/flutter_Test_Pj1/hoon_nexflex/flutter_application_1/ios/Pods/Firebase/CoreOnly/Sources/module.modulemap:0:7Error (Xcode): could not build module 'Flutter'/Users/hoon/development/flutter_Test_Pj1/hoon_nexflex/flutter_application_1/ios/Runner/GeneratedPluginRegistrant.h:9:8Error (Xcode): failed to emit precompiled header'/Users/hoon/Library/Developer/Xcode/DerivedData/Runner-awozdwnprnvtdrcrfughfazvzhji/Build/Intermediates.noindex/PrecompiledHeaders/Runner-Bridging-Header-swift_1TK2KTDMIUV5Y-clang_2JGQSHWY4RAHY.pch' for bridging header'/Users/hoon/development/flutter_Test_Pj1/hoon_nexflex/flutter_application_1/ios/Runner/Runner-Bridging-Header.h'Could not build the application for the simulator.Error launching application on iPhone 13.
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
SliverAppBar -> flexibleSpace에서 백그라운드 이미지 페이드아웃
안녕하세요 잘 보고 있습니다!! 플러터만세..CustomScrollView - SliverAppBar 뽀개버리기 강의에서,SliverAppBar에 flexibleSpace에 background에 image를 넣어서 스크롤을 위아래로 하실때 앱바에 이미지가 페이드 아웃 페이드 인 되듯이 자연스럽게 되는데 저는 이미지가 뚝 없어졌다가 뚝 생깁니다!! 따로 설정을 해주어야 하나요?
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
안녕하세요 선생님 또 저입니다
GoRouter 의 redirect 에 provider.redirectLogic 을 넣어주셨는데, 이렇게 설정하면 GoRouter 의 routes 안에서 이동이 일어날때마다 redirectLogic 이 실행되도록 구현하신게 맞나요? 제가 제대로 이해한게 맞는지 확인하고싶어서 글 남깁니다
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
안녕하세요 선생님 GoRouter 10 버전을 사용해보고 있는데요
기존에 4, 7 버전에서는 GoRouterState 에 location 속성이 있는데 10 버전에는 없더라구요.Uri 타입의 uri 가 새로 생겼던데location 대신 matchedLocation 을 사용해서 auth_provider.dart 를 만들어도 될까요?
-
해결됨[Bloc 응용] 실전 앱 만들기 (책 리뷰 앱) : SNS 로그인, Firebase 적용, Bloc 상태 관리, GoRouter
애플 개발자 홈페이지 관련
파이어베이스로 애플아이디 로그인을 연동하는 과정에 있는데요.혹시 애플 개발자 멤버십을 구입해야 식별자 등록 및 KEY 생성과 같은 여러가지 리소스를 이용할 수 있는건가요?
-
해결됨[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
Package 선택 어떻게 알아요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.코드팩토리 디스코드https://bit.ly/3HzRzUMFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다! ===================================프로젝트를 만들때 어떤 종류의 pub.dev package 들이 사용되는지 어떻게 알 수 있나요? 구글링인가요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
자동완성
너무 기초적인 질문이라 죄송합니다.강의 초반부에 StatelessWidget을 만드시는데 단축키를 사용하시는지 갑지가 몇글자 안치셨는데 비어있는 코드가 쭉 생기던데요.단축키인가요....???- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.코드팩토리 디스코드https://bit.ly/3HzRzUMFlutter 강의를 구매하시면 코드팩토리 디스코드 서버 플러터 프리미엄 채널에 들어오실 수 있습니다! 디스코드 서버에 들어오시고 저에게 메세지로 강의를 구매하신 이메일을 보내주시면 프리미엄 채널에 등록해드려요! 프리미엄 채널에 들어오시면 모든 질의응답 최우선으로 답변해드립니다!