앱 화면 만들기 2

윤주헌's avatar
Oct 01, 2024
앱 화면 만들기 2
notion image
div는 컴퍼넌트라 한다

1. 시작

notion image
순수하게 디자인을 home에 만들거임
네이게이션 뭐 설정해야 할게 많아서
Page를 하나의 스크립으로 볼거다
앱을 하나 만들었어
만든 페이지 개수 만큼 homePage가지면 된다?
 
블로그 목록
스캡폴더 구조?
수정화면 → 스캡폴더 구조 가져야 한다
글쓰기 → 스캡폴더 구조 가져야 한다

2. HomePage(메인 페이지)

  • 책임 하나의 화면
notion image
클래스 책임 분리
 
바뀐다면 WritePage() 이런 식으로 클래스로 분리
 
컬럼하고 비슷한데 스크롤이 있다
 

ListView 리스트로 쭉 보여짐 Colum과 같지만 스크롤이 있다.

notion image
 
notion image
 
notion image
이 코드 실행되면 중괄호 실행되는데 중괄호가 없다. 중괄호 넣으면 오류남
 
 

포 익스프레션

다트는 중괄호 안붙이면 익스프레션 표현할 수 있다
즉 리턴된다 for문이 리턴됨!!
 
익스프레션 표현식이다 리턴해줌
 
다트는 컬랙션안에 있으면 for문 쓸 수 있다
 
안되는 것
var data = for(int i =1 ; i<101; i++) i;
 
그래서
var list = [for(int i=1; i<11; i++) i]; print(lsit); 하면 [1,2,3,4,5,6,7,8,9,10] 이렇게 나온다
 
스크롤 생김
notion image
 
컬럼으로 바꾸면 됐을까?
안됨 터짐!!
notion image
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: ListView( children: [ for(int i=0; i<20; i++) Text("안녕"), ], ), ); } }
지우자

로우에 박스 4개 필요함

notion image

컨테이너 안에 차일드 가지고 있음

 
notion image
아이콘 넣어보자
notion image
notion image
 
Icon위젯은 아이콘 넣는건데 2가지 있음
  1. Icons.
  1. Icons.food_bank,
 
 
색 넣을 때는 colors
  1. Icons.food_bank, color: Colors.redAccent
 
notion image
 
객체를 넣은 것임 나머지 Icons, color, size는 선택적 매개변수
글자 찐하게 fontWeight :FontWeight.bold
색깔 color: Colors.
notion image
notion image
 

sizedBox

이미지, 단어 사이 간격 주기
 
notion image
 

컨테이너에 보더 주기

이제 보더만 주면 된다

decoraction : BoxDecoration()

notion image
 
추상클래스 new 못함 이거 구현한 구현체 있을거임
notion image
 
이거
notion image
 
막 찾지 말고 컨테이너 박스데코레이션 속성을 인터넷에 찾아라!!
 
 
notion image
 
동그랗게
notion image
notion image
 
컬럼안에 있는 애 기본배치가 위다! 스타트 위치
main인 세로 인 main에 center로
notion image
 
 
이거 4번 하면 된다
이거 cv하면 미친 짓이다!
메서드나, 클래스로 빼야한다!!
 
메서드로 빼는 거는 → 그 클래스에서만 사용할거면(이 화면에서만 사용할거면 메서드)
 
빼는 방법
notion image
notion image
notion image
다트 프라이베이트는 언더바 넣는다 문법이다!!
 
m은 내가 만든 메서드니까 m 붙인다!
 
notion image
 
먼저 만들고 추출하고 복사!!
 
다 동일하니까 인수만 바뀌면 된다 ()안에 들어가는 값
 
아이콘이 2가지 받아야 하는데
Icons, 글자 2가지 받아야 함
 
Icon의 타입? → IconDatat 타입
더 좋은 방법 타입 안 적으면 된다 안 적으면 var 타입 추론이다
이게 가능한게 다트다
notion image
텍스트는 $ 붙여주자 변수구나 확인할 수 있다
notion image
 
notion image
 
좋은점 !!
배치만 잘하면 재사용 가능하다1!!
 
notion image
화면
notion image
 
배치
스패이스 어라운드 하나 붙이고 끝내자
 
notion image
글자 크기
notion image
notion image
 
왼쪽에서 흘러오는 거니 스페이스 박스가 아니다!
 
그래서 스페이스 어라운드 넣어주자
notion image
화면
notion image
 
우리가 만들었다면 다이나믹인데
만약 다른사람이 이걸 쓴다면 빡친다 타입 안 적어주면
 
 
더 배려하려면 선택적 매개변수 해서 {required IconData mIcon, required String test} 이렇게
 
근데 다 짜놨는데 선택적 매개변수로 바꾸면 다 바꿔야 하니 싫다
그리고 키 값도 또 만들어야해서 불편하다
 
장단점이 있다
 
시그니처는 그냥 받고
받아도 되고 안 받아도 되는 애들을 선택적 매개변수로 정한다!
 
패딩 주기
큰 곳에 그래서
all말고
stmmetric으로
notion image
 
 
Row도 메서드로 빼버리자
notion image
Text도 메서드로 빼버리자
 
notion image
 
 

앱 바 넣기

스캡폴더 안에 넣어야 한다
notion image
 
앱 바 자리 정해져 있다.
 
리딩자리에 보통 뒤로가기 넣는다
notion image
notion image
 
리딩, 타이틀, 엑션자리 정해져 있다!
notion image
notion image
이런 식으로 앱 바에 색 넣을 수 있다
notion image
notion image
 
타이틀 리딩 지우고
 
notion image
notion image
 
 
일단 다자인 먼저 해야한다
 

Recipes 글자체 바꾸자

라이브러리 사용할 거임
 
인터넷
notion image
라이브러리 모여있는 오픈소스다!!
 
이거 사용할거임
notion image
 
 
스프링에서는 그레이들 사용함 실행파일 걸어주고 라이브러리 의존성 걸어주고 해줌
 
그래이들 썼는데 플러터에서는 의존성 관리 해주는 게 pub이라 한다
 
이거 리드미 파일이다 참고하자
 
notion image
복사
notion image
 
여기 넣자
notion image
notion image
넣고 pub get
 
이거 명령어로도 할 수 있다
notion image
$ flutter pub add google_fonts 복사해서 터미널에 넣고 엔터치면 알아서 생긴다 펍겟 할 필요 없음
 
사용법
notion image
통으로 복사해서 연습하는게 좋은데 지금은 모른게 많으니 리드미 가서
 
notion image
 
 
notion image
 
 
notion image
notion image
이게 더 좋은 코드 같다
notion image
 
patuaOne이 뭔지 어디서 봐야할까?
문서 아래 내리다 보면 있음
글자체
 
notion image
notion image
 
notion image
 
notion image
 
블락 → 넣으면 아래로 내려감
텍스트는 글자 크기만큼 인라인으로 커짐!
 
오늘 총 코드
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( actions: [ Icon(Icons.search), SizedBox(width: 16), Icon( CupertinoIcons.heart, color: Colors.redAccent, ), SizedBox(width: 16) ], ), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: ListView( children: [ _title(), SizedBox(height: 10), _menu(), SizedBox(height: 10), Container( height: 300, color: Colors.red, ), Placeholder(), Container( height: 300, color: Colors.red, ), ], ), ), ); } Text _title() { return Text( "Recipes", style: GoogleFonts.patuaOne( textStyle: TextStyle(fontSize: 30), ), ); } Row _menu() { return Row( children: [ _mIcon(Icons.food_bank, "ALL"), SizedBox(width: 25), _mIcon(Icons.emoji_food_beverage, "Coffee"), SizedBox(width: 25), _mIcon(Icons.fastfood, "Burger"), SizedBox(width: 25), _mIcon(Icons.local_pizza, "Pizza"), ], ); } Container _mIcon(IconData mIcon, String text) { return Container( width: 60, height: 80, decoration: BoxDecoration( border: Border.all(color: Colors.black12), borderRadius: BorderRadius.circular(30)), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( mIcon, color: Colors.redAccent, size: 30, ), SizedBox( height: 5, ), Text( "$text", style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold), ), ], ), ); } }
 
완성은 내일 다 한다!
notion image
 
잠시 있다가 함
 
 

컨테이너 설명

컨트롤 ww
notion image
패딩자리 삭제
 
변경
notion image
화면 뭐 안나오는게 맞음
notion image
 
안에 차일드 안에 컨테이너 만들기
notion image
notion image
ListView( children: [ Container( height: 300, width: 300, color: Colors.yellow, child: Container( height: 200, width: 200, color: Colors.red, ), ), ], )
빈박스 안에 빈 박스를 넣은거임
 
노란색 어디있냐? 빨간색 뿐임 이상함
notion image
 
컨테이너가 같은 자리를 갖고 있음
다시 말해 밖과 안의 컨테이너가 같은 자리 차지함
 
컬럼으로 변경
notion image
notion image
 
listView는 body가 감싸고 있음

LIstView 특징

위부터 앱바디 전체가 body영역, listView는 부모 크기만큼 늘어난다
세로는 무한이다 넓이는 부모의 크기만큼!!

Column특징

부모 쌩까고 자신의 크기만큼 커진다
세로방향 끝까지 자리를 차지한다
하지만 가로는 자식의 크기 만큼 차지한다
컬럼의 크로스 액시야스 기본이 center다
메인 액시야스는 기본이 start다
notion image
notion image
notion image
 
컨테이너를 컬럼 안에 두면
notion image
notion image
 
만약 화면의 가운데 두고 싶으면?
이 상태에서는 불가능함 컬럼의 크기가 왼쪽에 붙어있으니까
 
그래서 Row()의 제약 조건이 가로 화면 끝까지니까 가준다!
notion image
notion image
 
notion image
notion image
 
그러면 또 Row로 감쌀꺼야?
아님
Align으로 감쌈 정렬 하는 것 (부모가 전체를 차지해야 정렬이 가능하다)
notion image
notion image
 
 

Row특징

가로는 화면의 끝까지
세로는 자식의 크기만큼 차지한다
 

제일 중요한 것!

모든 위젯은 제약 조건이 있다
모든 제약조건은 바로위의 부모로 부터 받는다!!
부모의 부모의 제약조건 안 받고 싶으면 Row나 이런 것 넣어주면 된다
 
3가지 기억하자
  1. 컬럼은 세로의 길이 끝까지 차지하고 가로는 자식의 크기만큼, 디폴트 배치는 반대방향에 센터
  1. 로우는 높이 없고 가로 끝까지 차지한다. 로우 반대방향 정렬은 센터 로우의 세로크기는 아이탬의 크기, 세로의 크기는 자식 크기만큼 차지한다
  1. 모든 제약은 바로위의 부모로 부터 받는다
 
 
센터 위젯
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Constraints Example')), body: Center( child: Container( color: Colors.blue, constraints: BoxConstraints( minWidth: 100, minHeight: 100, maxWidth: 200, maxHeight: 200, ), child: Container( color: Colors.red, width: 30, height: 30, child: Center(child: Text('Child')), ), ), ), ), ); } }
뭐를 센터로 감쌌냐?
 
센터 색은 블루
근데 이 컨테이너 안에 자식이 있는데
래드다
notion image
 
자식 지우면
notion image
BoxConstraints가 있는데 제약조건 가지고 있고
컨테이너 크기가 없다!
범위를 안주면 맥스값으로 커진다!!
하지만 설정한다면 민과 맥스 사이 크기만큼 커진다 !
 
크기 500 500 설정해줘도 크기가 동일하다 왜?
최대값이 200으로 맥스 정해줬기 때문에!!
 
누구의 제약조건? 자기 자신의 제약 조건이다!
 
여기서 맥스 위더스가 300인데
여기에 double.infinity 하면
 
끝까지 늘어난다
값을 주지 않는다면!
notion image
notion image
이러면 설정값 안먹음
왜냐하면 최소도 끝가지 최대도 끝까지니까!
notion image
  • 중요!! 동작하는거 상상하고
굳이 내가 까볼필요 없이 제어할 수 없구나 ! 이해 해야한다!
 
minWidth를 100으로한다면 설정한 값으로 !
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Constraints Example')), body: Center( child: Container( color: Colors.blue, width: 300, constraints: BoxConstraints( minWidth: double.infinity, minHeight: 100, maxWidth: double.infinity, maxHeight: 200, ), ), ), ), ); } }
 
또 다른 밑에 것
위 컨테이너의 제약조건이 있다
이 상태에서 자식에 컨테이너가 생겼고
자식은 부모의 크기에 벗어날 수 있나 ? 못함 제약조건 자식까지 같이 생긴다
 
바로밑의 자식은 제약조건 물려받는다
 
위 아래 30인 자식 컨테이너줬음
 

랜더링의 순서

랜더링의 순서는 자식먼저 하고 그 다음 부모를 그린다!
 
부모의 크기가 없으면 자식에게 맞춰진다
근데 부모의 크기를 정해준다면 어떻게 될까?
빨간 박스가 커진다!
 
왜?
부모 크기에 정해짐
 

컨테이너 특징

  1. 자식이 없는 컨테이너는 가능한 박스를 크게 만드려고 한다 → 안 줬으면 더블 인피니티
notion image
notion image
  1. 자식이 있는 컨테이너는 자식의 크기에 맞게 조정된다! min값이 0 0 이니까
notion image
  1. 자식이 있는데 부모한테 위더스 100 헤이트 100 하면 지정한 크기에 맞춰진다
notion image
notion image
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Constraints Example')), body: Center( child: Container( width: 100, height: 100, color: Colors.blue, child: Text("안녕"), ), ), ), ); } }
 
파란박스안에 빨간 박스 넣고 싶다
이러면 안됨 부모 크기 있으니
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Constraints Example')), body: Center( child: Container( width: 300, height: 300, color: Colors.blue, child: Container( width: 100, height: 100, color: Colors.red, ), ), ), ), ); } }
그래서 이때 사용하는게 어라인이다
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Constraints Example')), body: Center( child: Container( width: 300, height: 300, color: Colors.blue, child: Align( child: Container( width: 100, height: 100, color: Colors.red, ), ), ), ), ), ); } }
컨테이너 안에 뭔가를 넣어 정리하려면 이 방법밖에 없다 바로 넣으면 크기 안 먹는다!
notion image
 
 
부모가 크기를 정한다면 자식은 크기를 따라간다
자식 크기 따라가려면 부모 크기가 없어야 한다
 
부모크기가
notion image
 
 

기억 중요!

컨테이너안에 넣으려면 cac
컨테이너 얼라인 컨테이너 !!
 

다시 시작

notion image
 
assets 파일 만들고 그 안에 사진 넣기
 
메인 다트 가서
notion image
근거는 있다
/붙이고 안 붙이고 근거
프로젝트 할 때 현재 위치가 중요하다
ip폴더여서?
/붙이면 안드로이드 이상한 위치?
뭐 일단 프로그램마다 다 다르다!
/붙였을 때 메인으로 가는가 안가는가 그것만 알면된다!
 
위젯
asset에 알트 엔터
notion image
notion image
 
notion image
notion image
이미지에는 반드시 fit을 줘야한다
notion image
 
가로모드면 조진다
만약 디바이스 크기가 엄청 길고 크다면 ListView니까 끝까지 늘어남
컬럼은 자신의 크기 만큼 늘어남
컬럼은 자식 크기에 맞춰져서 안됨?

사진할 때 반드시 이거 봐 꼭 비율 배치해!

사진은 무조건 비율을 줘서 배치해야한다!!
 
 
notion image
notion image
 
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( actions: [ Icon(Icons.search), SizedBox(width: 16), Icon( CupertinoIcons.heart, color: Colors.redAccent, ), SizedBox(width: 16) ], ), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: ListView( children: [ _title(), SizedBox(height: 10), _menu(), SizedBox(height: 10), AspectRatio( aspectRatio: 1.0, child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Image.asset("assets/coffee.jpeg", fit: BoxFit.cover), ), ) ], ), ), ); } Text _title() { return Text( "Recipes", style: GoogleFonts.patuaOne( textStyle: TextStyle(fontSize: 30), ), ); } Row _menu() { return Row( children: [ _mIcon(Icons.food_bank, "ALL"), SizedBox(width: 25), _mIcon(Icons.emoji_food_beverage, "Coffee"), SizedBox(width: 25), _mIcon(Icons.fastfood, "Burger"), SizedBox(width: 25), _mIcon(Icons.local_pizza, "Pizza"), ], ); } Container _mIcon(IconData mIcon, String text) { return Container( width: 60, height: 80, decoration: BoxDecoration( border: Border.all(color: Colors.black12), borderRadius: BorderRadius.circular(30)), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( mIcon, color: Colors.redAccent, size: 30, ), SizedBox(height: 5), Text( "$text", style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold), ), ], ), ); } }
나누기로 넣는게 좋다
 

비율

  • 1대 1비율
aspectRatio: 1/1,
 
  • 2대 1 비율
aspectRatio: 2/1,
 
  • 3대 1 가로길이 3 세로길이 1
aspectRatio: 3/1,
 
 
이거 잘라서 컬럼 만들어 주고 chidren 만들어서 안에 넣어주기
AspectRatio( aspectRatio: 3/2, //가로/ 세로 child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Image.asset("assets/coffee.jpeg", fit: BoxFit.cover), ), ), SizedBox(height: 10), Text( "coffee", style: TextStyle(fontSize: 20), ), Text( "Have you ever made your own coffee? Once you've tried a homemade coffee, you'll never go back.", style: TextStyle(color: Colors.grey, fontSize: 12), ),
 
 
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( actions: [ Icon(Icons.search), SizedBox(width: 16), Icon( CupertinoIcons.heart, color: Colors.redAccent, ), SizedBox(width: 16) ], ), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: ListView( children: [ _title(), SizedBox(height: 10), _menu(), SizedBox(height: 10), Column( children: [ AspectRatio( aspectRatio: 3 / 2, //가로/ 세로 child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Image.asset("assets/coffee.jpeg", fit: BoxFit.cover), ), ), SizedBox(height: 10), Text( "coffee", style: TextStyle(fontSize: 20), ), Text( "Have you ever made your own coffee? Once you've tried a homemade coffee, you'll never go back.", style: TextStyle(color: Colors.grey, fontSize: 12), ), ], ), ], ), ), ); } Text _title() { return Text( "Recipes", style: GoogleFonts.patuaOne( textStyle: TextStyle(fontSize: 30), ), ); } Row _menu() { return Row( children: [ _mIcon(Icons.food_bank, "ALL"), SizedBox(width: 25), _mIcon(Icons.emoji_food_beverage, "Coffee"), SizedBox(width: 25), _mIcon(Icons.fastfood, "Burger"), SizedBox(width: 25), _mIcon(Icons.local_pizza, "Pizza"), ], ); } Container _mIcon(IconData mIcon, String text) { return Container( width: 60, height: 80, decoration: BoxDecoration( border: Border.all(color: Colors.black12), borderRadius: BorderRadius.circular(30)), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( mIcon, color: Colors.redAccent, size: 30, ), SizedBox(height: 5), Text( "$text", style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold), ), ], ), ); } }
 
위젯으로 만들기!
notion image
 
notion image
 
RecipeItem
생성자 삭제
 
여기 패딩 줄거임
컬럼에 패딩
notion image
패딩 준거 다시 복구 시킬 수 있음
notion image

컨트스 설명

컨트스
상태 없을 때만 사용함
 
final 특징
💡
  • 런타임에 결정: final 변수는 선언과 동시에 값을 할당하지 않아도 되고, 나중에 한 번 할당될 수 있습니다.
  • 재할당 불가: 한 번 값이 할당되면 그 이후로 변경할 수 없습니다.
 
const 특징
💡
  • 컴파일 타임 상수: const로 선언된 값은 컴파일 시에 반드시 값을 알아야 합니다.
  • 리터럴 상수에 주로 사용됩니다.
  • 객체const로 선언하면 **불변 객체(immutable)**가 됩니다.
 
차이점
💡
  • final: 변수는 한 번만 값을 할당할 수 있고, 그 이후로는 변경 불가능합니다. 값은 런타임에 결정될 수 있습니다.
  • const: 변수나 객체의 값이 컴파일 타임에 고정되어야 하며, 이후에는 변경할 수 없습니다. 객체의 불변성을 보장합니다.
 
하지만 차이 한가지가 있다
 
const → 값이 무조건 있어야 한다
 
어떤 객체 new한다면 메모리에 뜨겠지
객체가 뜬다 플러터 엔진이 메모리 있는 객체 들고와서 그린다
 
만약 동일한 그림 10번 뜬다면 메모리에 1번만 뜨면 된다 → 동일하니까
 
이런 클래스를 변화가 없는 클래스다.
 
만약 로보트 3개 만들거다 전 세계에서
 
교실에 배치할거임 아무것도 안하고
메모리에 한번만 띄워서 만들어내면됨
 
이 3개는 같은 메모리를 공유한다!
new한거하고 그림 그린 것은 다르다!
만약 로보트 3개가 상태를 가진다면 어떻게 될까?
 
1개는 10시 되면 폭발 다른 1개는 2시 되면 폭발 3시 되면 폭발
그림이 같더라도 이렇게 상태가 다르면 new 3번 해야한다!!
 
상태가 다르면 메모리도 그 개수만큼 떠야한다
 
한번 띄워놓고 절대 안 변하는 것을 const로 만든다!
누가 new하면 const네 하고 절대 안 변하는거네 하고 가지고 온다!
 
const는 절대 안 변하는 것
 
const로 토토 3개 그렸어 근데 상태를 각 각 바꾸고 싶어
추후에 변화가 필요한 애는 const로 만들면 안 됨
 
상태를 가지면 const로 만들면 안됨!
 
const가지고 와서 쓸 때는
 
notion image
이 친구의 상태가 있나 없음!
3번 띄우고 3번그리는거나
1번 띄우고 3번그리나 같음
이럴려면 생성자 앞에 const 있어야 한다
 
const 붙이면 해시가 같다 즉 메모리 주소 같음!
 
언제 오류가 나나?
 
notion image
상태 들어오는 순간 const오류남!
 
이래 뜸
notion image
 
 
같은 값이 들어오면 하나만 뜨면됨!

컨스트 연습

class Dog { const Dog(); } void main() { Dog d1 = const Dog(); print(d1.hashCode); Dog d2 = const Dog(); print(d2.hashCode); }
 
상태를 넣었을 때 final하면
만약 상태가 같으면?(객체 공유 가능)
class Dog { final int age; const Dog(this.age); } void main() { Dog d1 = const Dog(10); print(d1.hashCode); Dog d2 = const Dog(11); print(d2.hashCode); }
 
만약 final안 붙었어
const지움
→ 이러면 10살 10살 한다고 메모리가 같을 까? 아님
class Dog { int age; Dog(this.age); } void main() { Dog d1 = Dog(10); print(d1.hashCode); Dog d2 = Dog(10); print(d2.hashCode); }
 
const사용하고 싶으면 클래스에 const가 있어야 사용 가능하다
 
근데 왜 SizedBox에 const붙여놨을까? 하나만 만들면 되는데 굳이 2개 new해야해?
성능이 변할 수 있다!
 
컨스트 붙여주는 라이브러리가 또 있다!
 
완성코드
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( actions: [ Icon(Icons.search), SizedBox(width: 16), Icon( CupertinoIcons.heart, color: Colors.redAccent, ), SizedBox(width: 16) ], ), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: ListView( children: [ _title(), SizedBox(height: 10), _menu(), SizedBox(height: 10), RecipeItem("burger.jpeg", "burger"), RecipeItem("coffee.jpeg", "coffee"), RecipeItem("pizza.jpeg", "pizza"), ], ), ), ); } Text _title() { return Text( "Recipes", style: GoogleFonts.patuaOne( textStyle: TextStyle(fontSize: 30), ), ); } Row _menu() { return Row( children: [ _mIcon(Icons.food_bank, "ALL"), SizedBox(width: 25), _mIcon(Icons.emoji_food_beverage, "Coffee"), SizedBox(width: 25), _mIcon(Icons.fastfood, "Burger"), SizedBox(width: 25), _mIcon(Icons.local_pizza, "Pizza"), ], ); } Container _mIcon(IconData mIcon, String text) { return Container( width: 60, height: 80, decoration: BoxDecoration( border: Border.all(color: Colors.black12), borderRadius: BorderRadius.circular(30)), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( mIcon, color: Colors.redAccent, size: 30, ), SizedBox(height: 5), Text( "$text", style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold), ), ], ), ); } } class RecipeItem extends StatelessWidget { String imageName; String text; RecipeItem(this.imageName, this.text); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 20), child: Column( //글자 가로 정렬 crossAxisAlignment: CrossAxisAlignment.start, children: [ AspectRatio( aspectRatio: 3 / 2, //가로/ 세로 child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Image.asset("assets/$imageName", fit: BoxFit.cover), ), ), SizedBox(height: 10), Text( "$text", style: TextStyle(fontSize: 20), ), Text( "Have you ever made your own $text? Once you've tried a homemade $text, you'll never go back.", style: TextStyle(color: Colors.grey, fontSize: 12), ), ], ), ); } }
Share article

code-sudal