묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
paginate() 에 대한 질문입니다.
void paginate({ int fetchCount = 20, // 추가로 데이터 더 가져오기 // true = 더 가져오기 // false = 새로고침 bool fetchMore = false, // 강제로 다시 로딩하기 // true - CursorPaginationLoading() bool forceRefetch = false, }) async { // 5가지 가능성 // State의 상태 // 1) CursorPagination - 정상적으로 데이터가 있는 상태 // 2) CursorPaginationLoading - 데이터 로딩중(현재 캐시 없음 // 3) CursorPaginationError = 에러가 있는 상태 // 4) CursorPaginationRefetching = 첫번째 페이지부터 다시 데이터를 가져올때 // 5) CursorPaginationFetchMore - 추가 데이터를 paginate 해오라는 요청을 받았을때 // 바로 반환하는 상황 // 1) hasMore == false(기존 상태에서 이미 다음 데이터가 없다는 값을 들고 있다면) // 2) 로딩중 - fetchMore : true // fetchMore : false - 새로고침의 의도가 있음. try { if (state is CursorPagination && !forceRefetch) { final pState = state as CursorPagination; if (!pState.meta.hasMore) { return; } } final isLoading = state is CursorPaginationLoading; final isRefetching = state is CursorPaginationRefetching; final isFetchingMore = state is CursorPaginationFetchingMore; if (fetchMore && (isLoading || isRefetching || isFetchingMore)) { return; } // PaginationParams 생성 PaginationParams paginationParams = PaginationParams( count: fetchCount, ); // fetchMore if (fetchMore) { final pState = state as CursorPagination; state = CursorPaginationFetchingMore( meta: pState.meta, data: pState.data, ); paginationParams = paginationParams.copyWith( after: pState.data.last.id, ); } final resp = await repository.paginate( paginationParams: paginationParams, ); if (state is CursorPaginationFetchingMore) { final pState = state as CursorPaginationFetchingMore; // 기존 데이터에 새로운 데이터 추가 state = resp.copyWith(data: [ ...pState.data, ...resp.data, ]); } else { state = resp; } } catch (e) { state = CursorPaginationError(message: '데이터를 가져오지 못했습니다.'); } } 이부분이 있는데왜 하위의 fetchMore의 else문에서 또 조건을 걸어놓는지 궁금합니다. // fetchMore if (fetchMore) { final pState = state as CursorPagination; state = CursorPaginationFetchingMore( meta: pState.meta, data: pState.data, ); paginationParams = paginationParams.copyWith( after: pState.data.last.id, ); } // 데이터를 처음부터 가져오는 상황 else { // 만약 데이터가 있는 상황이라면 기존 데이터 보존한 채로 Fetch(API 요청)을 진행 if (state is CursorPagination && !forceRefetch) { final pState = state as CursorPagination; state = CursorPaginationRefetching( meta: pState.meta, data: pState.data, ); } else { state = CursorPaginationLoading(); } }
-
미해결Flutter로 SNS 앱 만들기
메인화면에서 뒤로가기 눌렀을때 어플종료관련 건
메인화면에서 뒤로가기 눌렀을때 어플 종료를 하고 싶어서메인화면에서 WillPopScope( onWillPop: () async => false, 이 부분을 수정하였습니다. 수정한 결과 어플이 종료는 되나. 다시 어플을 실행했을때 splash화면에서 다음 화면으로 넘어가지 않습니다.. 아마도 사용자 정보를 가져오지 못해서 그런것 같은데.. 방법이 없을까요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
컨텍스트에 대한 질문
강의 보면 로그인 스크린의 빌드 컨텍스트 내부에 storage를 선언하셨는데, class _LoginScreenState extends State<LoginScreen> { String user = ""; String password = ""; @override Widget build(BuildContext context) { final storage = FlutterSecureStorage(); final dio = Dio(); final emulatorIp = '10.0.2.2:3000'; final simulatorIp = '127.0.0.1:3000'; final ip = Platform.isIOS ? simulatorIp : emulatorIp; return ...; } } 이 부분에서 왜 빌드컨텍스트 내부에 작성했는지 궁금합니다.
-
미해결Flutter로 SNS 앱 만들기
섹션8 게시글 정보가져오기
16:00 에러가 발생되었습니다. 어떻게 해야 하나요.ai로 질문의 답을 받았는데 잘모르겠습니다. void _getFeedList() { WidgetsBinding.instance.addPostFrameCallback((_) async { try { await feedProvider.getFeedList(); } on CustomException catch (e) { errorDialogWidget(context, e); // 에러출력 } }); }이부분을 어떻게 처리하면 됩니까
-
미해결[코드팩토리] [입문] Dart 언어 4시간만에 완전정복
4강애싱크 프로그래밍에서 12:46에서
4강애싱크 프로그래밍에서 12:46에서 addnumber함수는 비동기함수가 아니라 동기함수 아닌가요?그럼 위에 addnumber()가 끝나고(2초기다리는거까지 하고)나서 밑에 addnumber()가 실행돼야하는거 아닌가요??왜 위 addnumber의 2초를 기다리지 않고 밑에 addnumber를 실행하죠?Addnumber의 반환타입이 Future<void>가 아니라 그냥 void니까 동기함수 아닌가요??
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
에뮬레이터 오류
에뮬레이터가 실행은 되는데 컴퓨터 재부팅하고 나니 이런 메세지가 뜨고 계속 <no device selected> 로 나옵니다.실행을 해볼 수가 없어서 어떻게 수정하면 될까요? 코드팩토리 디스코드에 질문하면 더욱 빠르게 질문을 받아 볼 수 있습니다![코드팩토리 디스코드]https://bit.ly/3HzRzUM - 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
미해결Flutter로 SNS 앱 만들기
섹션8에서 게시글 정보 가져오기에서 timeStamp에러 입니다.
섹션8에서 게시글 정보 가져오기에서16:00WidgetsBinding.instance.addPostFrameCallback(callback) 나봅니다. 강의처럼 timeStamp가 나오지 않고,그래서 그냥 진행했습니다.WidgetsBinding.instance.addPostFrameCallback((_) async {그런데 다음과 같이 에러가 뜨네요.이런 메세지가 뜨는 이유가 뭔가요
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
객체 안에 객체가 있을때 모델링을
final List<Map<String,dynamic> products; 위와 같이 진행한다면factory RestaurantDetailModel.fromJson({ required Map<String, dynamic> json, }) { return RestaurantDetailModel( id: json['id'], name: json['name'], thumbUrl: 'http://$ip${json['thumbUrl']}', tags: List<String>.from(json['tags']), priceRange: RestaurantPriceRange.values.firstWhere( (element) => element.name == json['priceRange'], ), ratings: json['ratings'], ratingsCount: json['ratingsCount'], deliveryTime: json['deliveryTime'], deliveryFee: json['deliveryFee'], detail: json['detail'], products: List<Map<String, dynamic>>.from(json['products']), ); }fromJson 도 위와 같이 변경될 것 같은데, 이런 방식은 비효율적이거나 권장되지 않는 방식인가요?객체 안의 객체를 따로 모델링 하는 이유는 객체 안의 객체를 인스턴스화해서 재사용하는데 목적이 있는 건가요? 수업때 설명한 방식은 List 안에 Map 형태의 키값이 정해지지 않아 데이터 추출이 번거로워질 수 있다고 생각하면 되나요?
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
분명히 잘 따라했는데 일정 추가가 안되네요
분명히 잘 따라했고, 중간 중간 테스트 할때도 잘 됐는데 마지막에 onDismiss로 바꾼뒤로 갑자기 일정 추가가 안되는데..이유가 뭘까요?
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
실험으로 시간에 이상한값을 넣었는데..
테스트 해보려고 endTime에 41를 넣어서 저장을 눌렀는데 그 이후로 일정을 제대로 입력해도 일정이 아무것도 추가가 되지 않습니다. database에 문제가 생긴것같아서 sql파일을 초기화 해주고 싶은데 파일이 어디있는지도 잘모르겠네요..
-
미해결Flutter로 SNS 앱 만들기
8:18 저는 왜이리 이해가 안될까요. 보고 또보고 해도 포기해야 되겠죠...
Future<List<FeedModel>> getFeedList() async { QuerySnapshot<Map<String, dynamic>> snapshot = await firebaseFirestore .collection('feeds') .orderBy('createAt', descending: true) .get(); return await Future.wait(snapshot.docs.map((e) async { Map<String, dynamic> data = e.data(); DocumentReference<Map<String, dynamic>> writerDocRef = data['writer']; DocumentSnapshot<Map<String, dynamic>> writerSnapshot = await writerDocRef.get(); UserModel userModel = UserModel.fromMap(writerSnapshot.data()!); data['writer'] = userModel; return FeedModel.fromMap(data); }).toList()); }이부분에서 return await Future.wait(snapshot.docs.map((e) async { Map<String, dynamic> data = e.data(); DocumentReference<Map<String, dynamic>> writerDocRef = data['writer']; DocumentSnapshot<Map<String, dynamic>> writerSnapshot = await writerDocRef.get(); UserModel userModel = UserModel.fromMap(writerSnapshot.data()!); data['writer'] = userModel; return FeedModel.fromMap(data);이부분을 왜 이리 이해하기가 어려운지 모르겠어요..저만 그런가요...돌려봐도 싶지 않네요..
-
미해결[2024 최신] [코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
영화 평정 리뷰 프로젝트 문의
안녕하세요 강사님혹시 개정판 전 강의에 영화 평점 관련 강의가 있지 않았나요?다시 들어보려고 하는데 개정판에서는 없어진것 같습니다.혹시 그때 강의와 비슷한 강의 소개 또는 이전 강의 소스라도 받아 볼수 있을까요?
-
미해결Flutter로 SNS 앱 만들기
섹션7 게시글 등록화면에서 firestore작업에 Batch적용 부분에서 에니메이션과 Exception 발생하지 않습니다.
섹션7 게시글 등록화면에서 firestore작업에 Batch적용 부분에6:49 부분에서 테스트를 했는데 파일선택하고, feed버튼을 크릭하면 가로로 움직이는 에니메이션과 Exception 에러가 떠야하는데 뜨지않습니다. 아무리 봐도 그부분은 이상없는듯 한데 한번 봐주세요. 에러가 있으면 에러 처리라도 하겠는데 에러는 없습니다.압축파일과 함께 메일로 보냈습니다.
-
해결됨[Python 초보] Flutter로 만드는 ChatGPT 음성번역앱
음성인식 번역
음성인식으로 영어 인식은 잘 되는데 한국어 인식을 잘 못합니다한국어로 이야기를 해도 영어로 인식이 되는 문제가 있습니다
-
해결됨Flutter로 웹 서비스 개발하기 (1) - Responsive Web
SEO 강의 언제 나올까요?
seo 강의 인줄 알고 샀는데 아니였네욥.
-
미해결앱 개발 입문자를 위한 플러터 네컷일기 만들기 with 피그마
앱개발-입문자-플러터-네컷일기-with피그마 소스 다운로드
안녕하세요 [제로투원] 의 포레스트 입니다 :)제 강의를 선택해주셔서 감사합니다 !청강하시는 도중 질문사항이 있으시다면 언제든지 코멘트로 질문 바랍니다 소스 및 강의 자료 다운로드 받는 github url 이 있는지요? 좋은하루되세요 !
-
미해결[플러터플로우]코딩 없이 한 달 만에 앱 만들기
회원가입 시 프로필 설정으로 이동이 안되고, 버튼을 눌러도 로그아웃이 안됩니다.
회원가입 버튼의 action은 다음과 같습니다.로그아웃 버튼의 action은 아래와 같이 설정하였습니다. (두 버튼 모두 Navigate automatically는 off했습니다.)하지만 회원가입 후 프로필생성 페이지로 이동되지도 않고, 버튼을 눌러도 로그아웃이 되지를 않네요.. 이런 사례가 종종 있나요? 시크릿모드로 브라우저 열면서 계속 회원가입부터 다시 시작해도 똑같아요..
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
dio 네트워크 에러
강의를 진행하던 도중 재실행을 했더니 갑작스럽게E/flutter ( 7367): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioException [connection timeout]: The request connection took longer than 0:00:00.000000 and it was aborted. To get rid of this exception, try raising the RequestOptions.connectTimeout above the duration of 0:00:00.000000 or improve the response time of the server.E/flutter ( 7367): Error: SocketException: Connection timed out (OS Error: Connection timed out, errno = 110), address = 192.168.1.106, port = 39308E/flutter ( 7367): #0 DioMixin.fetch (package:dio/src/dio_mixin.dart:519:7)E/flutter ( 7367): <asynchronous suspension>E/flutter ( 7367): #1 LoginScreenState.build.<anonymous closure> (package:delivery/user/view/loginscreen.dart:77:36)E/flutter ( 7367): <asynchronous suspension>E/flutter ( 7367):dio의 연결초과 에러라고 뜨는데 해결방법을 모르겠습니다.잘 진행하다가 갑자기 이렇게 되버려서... 77번째줄 코드는 아래와 같습니다. final resp = await dio.post( 'http://ip/auth/login', options: Options( headers: { 'authorization': 'Basic $token', }, ), );
-
해결됨[Python 초보] Flutter로 만드는 ChatGPT 음성번역앱
음성인식 하는 마이크 시간이 짧은거 같아요
안녕하세요!섹션 7 Flutter음성대화 마지막 부분인 최종 테스트를 진행하고 있습니다음성인식이 가능은 합니다하지만 인식하는 시간이 짧아 긴 문장은 인식 못하는거 같습니다!!더 긴 문장을 말하고 싶은데 제가 말하는 음성인식 시간을 더 길게 할 수 있는 방법이 있을까요?? 제 코드 입니다오류나는 문제는 없습니다!!import 'package:dash_chat_2/dash_chat_2.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; // 통신을 할수있는 패키지 import 'dart:convert'; //파싱을 위한 import 'package:speech_to_text/speech_to_text.dart'; //stt 패키지 import 'package:speech_to_text/speech_recognition_result.dart'; //음성을 인식하는 import 'package:flutter_tts/flutter_tts.dart'; // class BasicScreen extends StatefulWidget { @override _BasicState createState() => _BasicState(); } class _BasicState extends State<BasicScreen> { bool isListening = false; // 기본 false SpeechToText _speechToText = SpeechToText();//SpeechToText 인스턴스(?) 생성 bool _speechEnabled = false; //음성인식이 가능한지 아닌지 상태 오류가 나면 인식이 나기 떄문에 사용 안함 isListening로 어느정도 대체 가능 String _lastWords = ''; //인식한 문장이 저장될 lastWords FlutterTts flutterTts = FlutterTts();//TTS 인스턴스(?) 생성 @override void initState() { //음성인식부분을 초기화 하는 코드 super.initState(); _initSpeech(); flutterTts.setLanguage("ko-KR");//인스턴스 언어 flutterTts.setSpeechRate(1.0);// 읽어주는 속도 } ChatUser user1 = ChatUser( id: '1', //우리 firstName: 'me', lastName: 'me', ); ChatUser user2 = ChatUser( id: '2', //chatgpt firstName: 'chatGPT', lastName: 'openAI', profileImage: "assets/img/gpt_icon.png" ); late List<ChatMessage> messages = <ChatMessage>[ //List<ChatMessage> = 채팅 메세지를 리스트 형태로 보관하는 ChatMessage( text: '반갑습니다. 어서오세요. 무엇을 도와드릴까요?', //보여지는 텍스트 user: user2, //누가 얘기하는지 user 설정 createdAt: DateTime.now(), //현재 대화가 발생한 날짜,시간 ), ]; @override Widget build(BuildContext context) { // 화면에 메세지를 보여주는 부분 return Scaffold( //Scaffold라는 형식으로 앱 구성을 묶어준것 appBar: AppBar( //AppBar는 타이틀 부분 title: const Text('Basic example'), ), body: DashChat( // DashChat패키지를 이용한 고유 클래스 / DashChat 정의를 해줌 currentUser: user1, //currentUser = 채팅을 입력하는 사람은 누구 onSend: (ChatMessage m) { setState(() {// setState = 현재 화면의 상황을 업데이트 해준다라고 이해하며 됨 messages.insert(0, m); //messages.insert = 메세지 전송 현재 사용자가 입력한 텍스트를 대화창으로 보내는 역할 ,리스트가 추가되는 거죠 }); Future<String> data = sendMessageToServer(m.text); //입력한 메세지를 받아서 서버에 전송을 해주고 data.then((value){ //결과값을 비동기(?) 형태로 받아와서 user2(chatgpt)가 발화(이야기)하고 통신 결과값을 출력하는 setState(() { messages.insert(0, ChatMessage( text: value, user: user2, createdAt: DateTime.now() )); }); }); }, messages: messages, inputOptions: InputOptions( leading: [ IconButton( icon: Icon(Icons.mic, color: isListening? Colors.red: Colors.black), //음성을 듣고있는 상태면 버튼누름 빨강 / 아니면 기본 검정 onPressed: (){ //아이콘이 눌러진다면 setState(() { //상태를 바꿔줘 isListening = !isListening; // 리스닝이 아닌 상태에 검정이 리스닝 상태인 빨강으로 바뀌는 처리 if (isListening == true){// 음성입력 대기 상태가 되면 print('음성인식 시작'); //폴스였다 트루가 되면 _startListening(); }else{ print('음성인식 끝'); // 트루였다가 풀스 _stopListening(); } }); }, ) ] ), ), ); } //통신을 할 수 있는 코드 = postman에서 테스트를 하면서 코드를 얻은것임,약갼의 수정을 해준것뿐 //json의 어떤 부분을 가져와야하는지 전체를 뿌릴순 없으니 추출하는 부분만 추가한것임 Future<String> sendMessageToServer(String messages) async{ var headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer sk-UGIfeFKyAXIhwIXdM3uf96g176CRFnw5AnHJ2acSpyT3BlbkFJmhIKdmcjh56e01G0Axc5xF9scspNoz_MsXuZPUGW8A', }; var request = http.Request('POST', Uri.parse('https://api.openai.com/v1/chat/completions')); request.body = json.encode({ "model": "gpt-4o-mini", "messages": [ { "role": "user", "content": messages, } ] }); request.headers.addAll(headers); http.StreamedResponse response = await request.send(); if (response.statusCode == 200) { String responseString = await response.stream.bytesToString();//json 문자열들이 string 변수에 저장이 된다 Map<String, dynamic> jsonResponse = json.decode(responseString);//responseString을 json 구조에 맞게 변환을 시킨게 jsonResponse가 된다 -> json 구조대로 입맞에 맞게 값을을 골라올수있음 String result = jsonResponse['choices'] != null? jsonResponse['choices'][0]['message']['content']: "No result found"; print(responseString); // 전체 내용 출력, 터미널 화면에서만 출력이 됨 실제 앱에서 출력되지 않음 그래서 return "ERROR"; 을 가지고있어야함 //message = 결과값 부분만 추출 , result라는 String에 저장 // 'choices' 조건문 return result; //함수를 호출한곳에서 사용을 할 수 있다 //print(await response.stream.bytesToString()); //await response.stream.bytesToString() = 실제 결과값 } else { print(response.reasonPhrase); return "ERROR"; // 오류가 날 경우 화면에서도 오류가 난걸 확인할 수 있게 해줌 } } /// This has to happen only once per app void _initSpeech() async { //초기화 하는 함수 , 마이크 같은 디바이스를 사용하기 떄문에 필요 print("음성인식 기능을 시작합니다."); _speechEnabled = await _speechToText.initialize(); //setState(() {}); } /// Each time to start a speech recognition session void _startListening() async { // start를 하게 되면 _onSpeechResult 부분을 동작을 시킴 print("음성인식을 시작합니다."); await _speechToText.listen(onResult: _onSpeechResult); //setState(() {}); } /// Manually stop the active speech recognition session /// Note that there are also timeouts that each platform enforces /// and the SpeechToText plugin supports setting timeouts on the /// listen method. void _stopListening() async { // 음성 인식 중지 print("음성인식을 종료합니다."); await _speechToText.stop(); //setState(() {}); } /// This is the callback that the SpeechToText plugin calls when /// the platform returns recognized words. void _onSpeechResult(SpeechRecognitionResult result) { _lastWords = ""; //초기화 시킴 , 입력을 받을떄마다 새롭게 리셋해야하기 떄문에 추가 if(result.finalResult){ //최종인식 _lastWords = result.recognizedWords; //result에 recognizedWords를 _lastWords에 넣어줘 print("최종 인식된 문장: $_lastWords"); //flutter 에서는 변수를 텍스트 안에 넣어줄때 $를 넣고 일반 텍스트문자영하고 변수가 가티 출력됨 / 최종 인식된 음성을 텍스트로 바꿔서 _lastWords 넣어줘 setState(() { //messages 리스트에 인식한 내용을 추가해줘. messages.insert(0, ChatMessage( text: _lastWords, user: user1, createdAt: DateTime.now() )); }); Future<String> data = sendMessageToServer(_lastWords); //입력한 메세지를 받아서 서버에 전송을 해주고 data.then((value){ //결과값을 비동기(?) 형태로 받아와서 user2(chatgpt)가 발화(이야기)하고 통신 결과값을 출력하는 setState(() { messages.insert(0, ChatMessage( text: value, user: user2, createdAt: DateTime.now() )); }); flutterTts.speak(value); // value를 바로 읽어줌 }); } } }
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
이 부분에서 Error: The argument type 'RestaurantDetailModel' can't be assigned to the parameter type 'RestaurantModel'.
import 'dart:convert'; import 'dart:async'; import 'package:colorfactor/common/const/data.dart'; import 'package:colorfactor/common/layout/default_layout.dart'; import 'package:colorfactor/product/component/product_card.dart'; import 'package:colorfactor/restaurant//component/RestaurantCard.dart'; import 'package:colorfactor/restaurant/model/restaurant_detail_model.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; class RestaurantDetailScreen extends StatelessWidget { final String id; const RestaurantDetailScreen({super.key, required this.id}); Future<Map<String, dynamic>> getRestaurantDetail() async { final dio = Dio(); final accessToken = await storage.read(key: ACCESS_TOKEN_KEY); final resp = await dio.get('http://$ip/restaurant/$id', options: Options( headers: { 'authorization': 'Bearer $accessToken' }, ), ); return resp.data; } @override Widget build(BuildContext context) { return DefaultLayout( title: '불타는 덕볶이', child: FutureBuilder<Map<String, dynamic>>( future: getRestaurantDetail(), builder: (_, AsyncSnapshot<Map<String, dynamic>> snapshot) { print(snapshot.data); if (!snapshot.hasData) { return Container(); } final item = RestaurantDetailModel.fromJson( json: snapshot.data!, ); return CustomScrollView( slivers: [ renderTop( model: item, ), renderLabel(), renderProducts(), ], ); } ), ); } SliverPadding renderLabel() { return SliverPadding( padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverToBoxAdapter( child: Text( '메뉴', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),), ), ); } renderProducts() { return SliverPadding( padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverList( delegate: SliverChildBuilderDelegate((context, index) { return Padding( padding: const EdgeInsets.only(top: 16.0), child: ProductCard(), ); }, childCount: 10, ), ), ); } SliverToBoxAdapter renderTop({ required RestaurantDetailModel model, }) { return SliverToBoxAdapter( child: RestaurantCard.fromModel( model: model, isDetail: true, ), ); } }이 강의 진행에서 SliverToBoxAdapter renderTop({ required RestaurantDetailModel model, }) { return SliverToBoxAdapter( child: RestaurantCard.fromModel( model: model, isDetail: true, ), ); } }이 부분에서 Error: The argument type 'RestaurantDetailModel' can't be assigned to the parameter type 'RestaurantModel'.이 에러가 뜹니다. 구조를 다시 따라가서 봐도 문제가 없는것 같은데, 아직 이해도가 낮아서 그런지 Detail모델이 왜 Model에 대입되는지가 이해가 안됩니다.