좋아요 기능 구현
좋아요 기능을 구현하기 위해서는 현재 내가 보고 있는 페이지에 상태가 변하기 때문에(어떠한 로직으로 화면의 변화가 생기는것)
그 해당 페이지의 State를 바꿔줘야한는데
class Feed extends StatelessWidget {
const Feed({
super.key,
});
현재 Feed라는 페이지는 StatelessWidget으로 되어있다. 이것을 안드로이드스튜디오 기준
맥 option + Enter / 윈도우 Alt + Enter 를 눌러주면
위 사진 처럼 자동으로 StatefulWidget으로 변환하여 줍니다.
나도 잘 모르지만 해석해보자면
@override = class Feed extends StatelessWidget 을 재정의 하겠다.
State<Feed> createState() => _FeedState(); = Feed 클래스의 createState를 재정의하고 _FeedState에 반환하겠다.
class _FeedState extends State<Feed> = 새롭게 만들어진 _FeedState를 기존 Feed와 연결하겠다.
라고 해석되며 사실 간단히 넘어가도 될것 같지만.. 궁금해서 알아봤습니다.
class Feed extends StatefulWidget {
const Feed({
super.key,
});
@override
State<Feed> createState() => _FeedState();
}
class _FeedState extends State<Feed> {
@override
Widget build(BuildContext context) {
return Row
StatefulWidget이 된 모습
그리고
좋아요하지 않은 것(false) 좋아요한 것(true)의 값을 만들어 줘야하기때문에
_FeedState 안에 bool isFavorite = false; 를 입력하여 줍니다.
class _FeedState extends State<Feed> {
bool isFavorite = false;
@override
Widget build(BuildContext context) {
이렇게 세팅을 다 해주었다면 좋아요 기능을 구현할 항목에 가서
GestureDetector > onTap > setState > isFavorite = !isFavorite; 를 입력하여줍니다.
Row(
children: [
Spacer(),
GestureDetector(
onTap: () {
setState(
() {
isFavorite = !isFavorite;
},
);
},
이런식으로! 위에서 부터 천천히 읽자
제스처를 감지하는 위젯.. 눌렀을때 위젯... 상태를 바꿔주는 위젯... isFavorite의 bool값을 반전시켜주는 함수실행..
여기서
onTap 에서도 더블탭, 꾹누르기 같은 기능들을 구현할 수 있으며
함수 앞에 !를 붙이면 bool 값을 반전 시켜주는 토글키라고 생각하면 되겠습니다. (true <-> false)
그리고 함수안에 print(isFavorite); 를 넣어 작동되는지 확인해봅니다.
그러나 시뮬레이터에서는 그대로일텐데 이는 당연히 false일때의 이미지 true일때의 이미지를 따로 설정해주지 않아서 그렇습니다.
아래에 아이콘 항목으로 가서 본인으 원하는 아이콘과 색상을 입력해주면 됩니다.
Icon(
isFavorite
? CupertinoIcons.heart_fill
: CupertinoIcons.heart,
color: isFavorite ? Colors.pink : Colors.black,
size: 16,
),
여기서 물음표(?) 와 콜론(:) 이 나오는데 삼항연산자로써 if문, 조건문과 비슷한 역할입니다.
원래는
Icon(
if (isFavorite == false) {
CupertinoIcons.heart }
else {CupertinoIcons.heart_fill}
),
이런식으로 if문으로 할 수 있지만 javascript기반의 언어라서 그런지 변수 내에서 if문은 사용은 안되는것 같다..
조건 ? 값1 : 값2
true일때 값1, false일때 값2를 반환한다.
그리고 구색은 갖추고 싶어서
토글키를 만들고
onTap에 토글키를
텍스트에
num값을 넣고
숫자도 같이 올라갔다 내려갔다 할 수 있도록 만들었다...!
리스트 만들기
home_page.dart 파일에 Feed를 자동완성(Ctrl + SpaceBar)을 통해Builder로 감싸줍니다.
그리고 그 Builder를 Listview.builder로 바꿔줍니다.
Listview는 일반 builder가 아닌 itemBuilder를 받기 때문에 이부분 또한 자동완성을 통해 바꿔줍니다.
또한 itembuilder는 context를 포함하여 int값 즉 index를 포함하여야 합니다.
그렇게 만들고보면 시뮬레이터에서 한가지 문제가 발생합니다.
이런식으로 무한스크롤이 발생합니다. 이러한 경우에는
itemCount: 10, 을작성하여 ListView가 보여주는 리스트의 갯수를 정해줄수 있습니다.
만약 List<>를 작성해두셨다면 List.length로 그 List의 index갯수만큼 리스트를 보여줄 수 있습니다.
참고로 이 ListView를 사용하게 되면 스크롤을 자동으로 할수있게 되는데 SingleChildScrollView()를 사용하게된것 과 동일한 효과를 볼 수 있습니다.
그리고 ListView.builder를 List.separated로 바꿔주면서 아래에 saparatorBuilder함수를 추가해준뒤 가로선을 추가하는 Divider를 추가해주면
이렇게 가로선이 생긴걸 확인할 수 있다.
그리고 ListView에 horizontal 패딩을, Feed에 verical 패딩을 넣어주면
이렇게 좀더 보기좋게 만들수 있었다.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'bottom_bar.dart';
import 'feed.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 1,
shadowColor: Colors.black,
leading: Row(
children: [
SizedBox(width: 16),
Text(
'중앙동',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
Icon(
Icons.keyboard_arrow_down_rounded,
color: Colors.black,
),
],
),
leadingWidth: 100,
actions: [
IconButton(
onPressed: () {},
icon: Icon(CupertinoIcons.search, color: Colors.black),
),
IconButton(
onPressed: () {},
icon: Icon(Icons.menu_rounded, color: Colors.black),
),
IconButton(
onPressed: () {},
icon: Icon(CupertinoIcons.bell, color: Colors.black),
),
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: ListView.separated(
itemCount: 10,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Feed(),
);
},
separatorBuilder: (context, index) {
return Divider();
},
),
),
floatingActionButton: FloatingActionButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(125),
),
onPressed: () {},
backgroundColor: Color(0xFFFF7E36),
elevation: 1,
child: Icon(
Icons.add_rounded,
size: 36,
),
),
bottomNavigationBar: BottomBar(),
);
}
}
'Flutter > App Making Learn' 카테고리의 다른 글
[플러터 Flutter] 약관 동의 페이지 만들기1 (on/off 토글키 및 bool타입 선언) (0) | 2024.06.12 |
---|---|
플러터 당근마켓 앱 카피코딩3 (피드정리) (0) | 2024.05.06 |
플러터 당근마켓 앱 카피코딩1 (appBar, body, floatingActionButton, bottomNavigationBar) (4) | 2024.04.30 |
플러터 ListView.builder 가로 스크롤, TextField clear (0) | 2024.04.30 |
[플러터] 로그인화면 만들기 (1) | 2024.04.26 |