Flutter Study (3)

cheeseonrose·2023년 4월 10일
0

파일 분리

  • 모든 코드가 main.dart에 있으면, 코드가 길어질수록 코드를 찾는 시간이 길어진다.
  • 위젯들을 각각 다른 파일로 분리할 것

파일 구조

  • main.dart : 앱 시작
  • home_page.dart : 첫 번째 페이지 레이아웃
  • feed.dart : HomePage의 body
  • Widget 분리하기
    • 분리할 Widget에서 우클릭 -> Refactor -> Extract Widget (노란 전구 클릭해도 가능)
    • 분리한 Widget을 별도의 파일로 옮기면 끝
  • Refactoring(리팩토링) : 기능을 변경하거나 추가하지 않고, 코드만 관리하기 쉽게 변경하는 과정



좋아요 구현하기

아이콘 색상 변경하기

  • Feed Widget을 StatefulWidget으로 변경
    • 좋아요 여부에 따라 화면을 갱신해야 하기 때문
    • StatelessWidget 클릭 -> ctrl + . -> Convert to StatefulWidget
  • isFavorite 상태 추가
    class _FeedState extends State<Feed> {
    	bool isFavorite = false; // 좋아요 여부
    	...
    }
  • GestureDetector의 onTap 함수에 setState 로직 넣어주기
    GestureDetector(
    	// 위젯을 버튼처럼 만들 수 있음
    	onTap: () {
    		setState(() {
    			isFavorite = !isFavorite;
    		});
    	},
    	...
    )
  • isFavorite 값에 따라 색이 바뀌도록 Icon 안에 로직 추가
    Icon(
    	isFavorite
    		? CupertinoIcons.heart_fill
    		: CupertinoIcons.heart,
    	color: isFavorite ? Colors.pink : Colors.black,
    	size: 16,
    )
    • 조건 ? 반환값1 : 반환값2
      • 조건이 true인 경우 반환값1이 할당되고 , false인 경우 반환값2가 할당됨



피드 리스트 만들기

ListView Widget

  • 동일한 레이아웃에 다른 정보를 보여줄 때 사용하면 유용한 위젯
  • SingleChildScrollView + Column과 비슷하다.
    ListView(
    	children: [
    		Text("0"),
    		Text("1"),
    		Text("2"),
    		...
    	]
    )

ListView.builder

  • 적은 코드로 itemCount만큼 화면을 그릴 수 있다.
    ListView.builder(
    	itemCount: 100,	// 전체 아이템 개수
    	itemBuilder: (context, index) {	// index는 0~99
    		return Text("$index");
    	}
    )

ListView를 사용하여 Feed 보여주기

  • Feed Widget을 Refactor -> Wrap with Builder -> ListView.builder로 바꿔줌

ListView.separated

  • 각각의 Feed 사이에 Divider를 추가
    ListView.separated(
    	itemCount: images.length,
    	itemBuilder: (context, index) {
    		return Feed();
    	},
      	separatorBuilder: (context, index) {
      		return Divider();
      	},
    )



이미지 보여주기

Feed에 imageUrl 받아오기

  • Feed Widget에 imageUrl 변수 생성

    class Feed extends StatefulWidget {
        const Feed({
          Key? key,
          required this.imageUrl,
        }) : super(key: key);
    
    	final String imageUrl;
    		...
    }
  • Image.network에 받아온 imageUrl 넣어주기

    ClipRRect(
    	borderRadius: BorderRadius.circular(8),
      	child: Image.network(
      		widget.imageUrl,
            width: 100,
            height: 100,
            fit: BoxFit.cover,
        ),
     )
    • widget.imageUrl인 이유
      • imageUrl이라는 변수는 _FeedState 클래스 안에 존재하지 않음 -> Feed 클래스 안에 존재
      • State 클래스에서 자신이 속한 Widget의 변수를 가져다 사용하기 위해 "widget.변수"를 사용

Feed에 데이터 전달하기

  • images 리스트에서 url 가져오기
    ListView.separated(
    	itemCount: images.length,
      	itemBuilder: (context, index) {
        	final image = images[index];
        	return Padding(
                padding: const EdgeInsets.symmetric(vertical: 12),
                child: Feed(imageUrl: image),
            );
        },
        ...   
    )



완성된 화면

carrot_market GitHub

0개의 댓글