이번 포스트에는 페이지뷰(PageView)를 이용해서 여러장의 한포스트에 여러장의 사진을 담아서
오른쪽으로 스와이프해서 사진을 넘기는거를 해볼거에요.
금일 작업 내용
1.PageView 위젯 생성
2.AspectRatio 로 비율주기
3.Indicator 달아주기
4.Stack 사용하기
5.PageView.builder 사용하기
6.CurrentPage 표시하기
1.PageView 위젯 생성
먼저 기존에 이미지가 담긴 Container를 PageView로 감싸줘요.
children 부분에 기존의 이미지가 담긴 Container 를 그냥 담아주면되요. 저는 3개 담아줬어요.
그럼 3장의 사진을 넘길수 있게되겠죠.
그런데 이런 사이즈 오류가 날거에요.
페이지뷰를 쓰기위해서는 부모위젯이 세로 사이즈를 가지고 있어야하는데
사이즈를 담는방법은 여러가지가 있어요.
대표적으로 기본적으로 PageView를 다시 Container로 감싼뒤 height 를 주는 방법이 있어요
그런데 저는 AspectRatio 라는걸로 세로사이즈를 줄거에요.
2.AspectRatio 로 비율주기
어떻게 그게 세로사이즈를 줄수있느냐?
AspectRatio 는 비율을 주는건데 여기에서 비율을 1로 주면 가로가 100이라면 세로는 자동적으로 100이되겠죠
그래서 세로 길이를 주는것과 마찬가지가 되요.
여기서 가로는 부모위젯의 가로를 따라가는데 현재 AspecRatio를 또 담고있는 최상위 위젯의 가로가 현재 에뮬레이터의 가로값으로 되어있어요.
패딩이라던가 별다른거를 안했으면 그냥 에뮬레이터 가로가되요.
예를들어 기계가로가 300이면, 자동적으로 AspecRatio가 담고있는 가로는 300일텐데,
제가 AspecRatio를 담고있는 위젯에 가로패딩을 10씩줬다고 가정하면, 양쪽에 10씩빼니까
AspecRatio가 담고있는 가로는 280이 될것이고, AspecRatio의 비율값을 1로 조절하면 세로는 280이 되겠죠.
여기서 비율값 1이란것은 가로/세로 에요.
1은 가로 =세로 인것이고
1.5 이렇게 됫다하면 가로길이가 더 긴거겠죠.
그래서 1을 기준으로 1보다 크면 가로가 더긴거고 1보다작으면 세로가 더 긴거에요.
이렇게 하니 가로 세로 길이가 1:1 이라서 정사각형이 되죠.
여기서 사진이 위아래로 잘렸는데
사진의 fit 부분을 BoxFit.cover 로 줬기 때문이에요.
cover는 사진을 가로든 세로든 부모에 맞을때까지 최대한 키운다음 넘기는부분은 잘라버리는거고
contain은 가로든 세로든 먼저 도달하는놈있으면 그걸 기준으로 사진키우기를 멈춰요.
사실 나도 설명이 잘안되는데, cover를 container 로 바꿔볼게요
비교해서 한번 보죠.
이렇게 되요. 무슨 차이인지 아시겠죠?
근대 사진이 안짤리는것도 중요한데 사진이 저렇게 빈공간이 있으면 이상하니까
그냥 저는 cover로 할게요.
그런데 인스타 보면 모든 포스트의 사진부분 비율이 1이 아니잖아요?
어떤건 세로가 길고 어떤건 세로가 짧고, 포스트 마다 다른걸 볼수있어요.
그런데 사진을 옆으로 스와이프해서 속해있는 다른사진들을 보면 cover로 되어있어서 빈공간이 안나타죠
대신에 조금 짤려있죠.
그런데 첫번째 사진은 안짤리죠.. 첫번째 사진만큼은 제대로 보여주고, 나머지는 잘리든 말든 나둔거죠
첫번째 부터 사진이 잘리면 이상하잖아요.
그래서 아이디어는 첫번째 사진의 비율을 기준으로 AspecRatio 비율값을 주는거에요.
그런데 지금은 첫번째 사진의 비율을 가져오는게 굉장히 복잡해요. 왜냐하면 데이터베이스에서 자료를 가져오는게 아니라 사진의 url 을 인터넷에서 그냥 가져오기 때문이죠.그래서 나중에 데이터베이스에 사진을 올릴때 가로,세로 사이즈를 올려놓고 그걸 참고로할거에요.그런데 지금은 데이터베이스에 있는 내용을 쓰는게 아니라 연습이기 때문에
그냥 비율을 랜덤으로 줄게요. 이 랜덤비율이 나중에는 첫번째 포스트의 비율이 될거에요.
이렇게 비율을 Random().nextDouble() +Random().nextDouble() 로 줬어요.
그이유는 Random().nextDouble() 이라고하면 0.0부터 1.0 까지 랜덤으로 나타내는데
저는 0.0부터 2.0 까지 나타내고 싶거든요.
어떻게 아다리가 잘못걸려서 0.0+0.0나오면 이상하겟죠?
그러니 0.5+Random().nextDouble() +Random().nextDouble() 라고 하면 되겠죠
그러면 최소 0.5 고 최대 2.5가 되겠죠?
근데 0.5부터 2사이로 만들고 싶다?
그러면 어떻게 생각을 동원해서 할수는 있겠지만, 지금이시점에서 그걸 고민하는건 의미없다고 봐요.
어쨋든 이것도 임시적으로 저렇게 적는거니깐요
근데 정 해야겠다. 그렇다면 저는 이런방법을 쓸거에요
5부터 20까지의 숫자를 랜덤으로 뽑고 거기에 0.1을 곱하는거죠.
그럼 0.5부터 2까지 범위가 되겟죠
어쨋든 이렇게하면 각포스트의 높이가 달라진걸 볼수잇어요.
지금은 첫사진이든 뒤에있는 사진이든 전부 잘리지만
나중에 비율부분을 첫사진에 맞추면 첫사진만큼은 안잘릴거에요. 그래서 지금은 좀 이상해도 참아봅시다.
3.Indicator 달아주기
그다음은 인디케이터를 달아줄거에요
밑에보면 점박이같은거 있잖아요 그거에요
scrolling_page_indicator 라는 라이브러리를 깔아줍니다.
pubspec.yaml에 깔아주시구요
그다음 일단
저렇게 PageController 변수를 만들어주세요.
그리고 PageView 에 controller 라는 옵션에다가 앞서 생성한 컨트롤러 변수를 넣어줍니다.
아까 PageView를 AspectRatio로 감쌋었잖아요?
그거 밑에다가 적어봅니다.
ScrollingPageIndicator(
dotColor: Colors.grey,
dotSelectedColor: Colors.deepPurple,
dotSize: 6,
dotSelectedSize: 8,
dotSpacing: 12,
controller: _controller,
itemCount: 3,
orientation: Axis.horizontal
),
이거 그냥 복붙해서 넣어셔도되고, 사이즈나 색상은 맘대로 조절해서 넣으시면되는데
controller 랑 itemCount를 잘넣으셔야되요
controller는 아까만든 컨트롤러 넣으시면되고
itemCount는 PageView에 사진갯수랑 동일하면되겟죠.
그럼 오른쪽처럼나와요.
근대 우리가 이미 indic 이라고 인디케이터 넣을자리를 만들어 둿잖아요?
그러니 거기에다가 제대로 넣어줍시다.
이렇게 그대로 심어주는거죠
이렇게하니 딱 그자리에 들어왓긴하는데
센터 자리가 안맞네요.
그이유는 spaceBetween 때문이에요
spaceBetween 은 저기 빨강색 부분을 같게 해줘야되는 의무가 있기 때문이죠
그래서 저는 기존 부분을 지우고 Stack 이라는것을 쓸거에요
4.Stack 사용하기
Stack 은 겹치기에요
이렇게 한다음 alignment 를 center로 하는거죠.
그런데 ScrollPageIndicator 인데 스크롤되는게 안보이잖아요?
왜냐하면 갯수가 3개밖에 안되니까 에요.
그래서 한 7개 해볼게요
그러면 PageView 에 담기는사진도 7개여야되겟죠
이렇게 PageView 이하 chidren에 7개 주시고
itemCount를 7개로 해줘요
그러면 이렇게 롤러블이 되겠죠.
그런데 우리가 아까 아이템 갯수를 7개를 줄때 노가다를 했잖아요.
아무리 하드코딩이지만 바람직하지 않죠.
그래서 그걸좀 손볼게요
5.PageView.builder 사용하기
먼저 pageLength 라는 변수를 만들어 줍니다.
그다음 InitState 부분에
저렇게 적어줘요
그러면 위젯이 호출될때 처음에 pageLength 라는것이 정해져요.
이거는 3부터~7까지의 값을 가지겠죠(3+(0 or 1 or 2 or 3 or 4))
그다음 기존에 그냥 PageView 였다면 이번에는 PageView.builder 로 바꿔줘요.
코드가 아주 간편해졌네요.
여기 itemCount 속성에 pageLength 변수를 넣어줍니다.
controller 도 잘 넣어주시구요.
그리고 ScrollingPageIndicator 로 가서 itemCount에 pageLength 변수를 달아줍니다.
그러면 어떤거는 3개 어떤거는 7개 이런씩으로 랜덤하게 되겠죠.
근데 계속말씀드리지만 지금은 하드코딩이라서
갯수도 랜덤으로 이렇게 하지만 결국은 데이터 베이스의 정보기준으로 갯수도 정해지는거에요.
그러면 데이터베이스를 다뤄서하는건 언제하느냐? 그건 곧 할거에요. 일단 하드코딩으로 좀 익숙해지도록 합시다.
자 아직 안끝났어요.
인스타 보면 저기 숫자 표시 저거 해볼게요.
6.CurrentPage 표시하기
PageView.builder 를 Stack으로 감싸줘요.
그리고 alignment를 topRight 로 해줘요.
그리고 아래 사각 박스를 만들어줍니다.
그리고 임의적으로 텍스트에 4 / 7이라고 넣어봤어요
그러면 저렇게 사각 박스가 나오는걸 볼수있어요.
그러면 일단 너무 사각형이니까 좀 둥그스름하게 하고 좀더 이쁘게 해볼게요
이렇게 하면 조금더 괜찮아 진거 같나요?
여기서 4/7 은 그냥 적어 둔거니까 저거 지우고 진짜로 해봅시다.
먼저 변수를 생성해요. currentPageIndex 라고 해두고 초기값을 0으로 했어요.
그다음 PageView.builder 에 onPageChanged 라는 옵션에 저렇게 해줬어요.
그리고 4/7 이라고 임의로 적어둔곳에 저렇게 바꿔줬어요.
이렇게 하니 밑에 gif 처럼 되죠
그런데 움직일때마다 사이즈가 변경이돼죠?
그건 setState 하면서 Random 함수를 계속 부르면서 비율을 바꾸 바꾸기 때문에요.
그래서 요거도 좀 고쳐줍시다.
아래 사진처럼 initRatio 라는 변수를 만들고 여기에 0.5 라는 초기 값을 줬어요,
그리고 initState 가 실행될때
initRatio=testint[Random().nextInt(16)]*0.1; 이렇게 될수있도록 했죠.
그다음
aspectRatio 를 이렇게 수정해줬어요.
그러면 이렇게 그럴듯하게 나와요.
근데 스와이프 할때마다 밑에 좋아요 개수도 바뀌는데
이것도 랜덤함수가 계속불려져서 그런거니 똑같은 맥락으로 바꿔주면 되요.
그런데 그럴필요가 없죠. 어차피 하드코딩으로 레이아웃만 보는 단계니까요.
그럼 이렇게 페이지뷰를 활용한 단계를 마치도록 할게요.
-----------------공지-------------------
23년 버전 앱강의를 오픈했습니다. 관심있으신분은 클릭 ㅋㅋ
2023.07.29 - [코딩생초보를 위한 플러터 빠르게 한바퀴] - 1. create project
개인과외 문의 saran.flutter@gmail.com
'플러터로 앱만들기' 카테고리의 다른 글
플러터로 SNS어플 만들기 10.데이터베이스 만들기-파이어베이스 파이어스토어(firebase-firestore) 연결하기 2 (1) | 2021.05.23 |
---|---|
플러터로 SNS어플 만들기 9.데이터베이스 만들기-파이어베이스 파이어스토어(firebase-firestore) 연결하기 1 (0) | 2021.05.21 |
플러터로 SNS어플 만들기 7.하드코딩으로 레이아웃잡기 (0) | 2021.05.17 |
플러터로 SNS어플 만들기 6. ListView 이용하여 리스트뿌려주기 (2) | 2021.05.15 |
플러터로 SNS어플 만들기 5. font 적용하기 (0) | 2021.05.13 |