[Fluttet] 플러터 앱 예제 가게 이름 선택하기 예제 (하) (삼항연산자)
안녕하세요! 이전에 했던 예제를 이어서 진행해보겠습니다. price와 title은 가져와보셨나요?
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(60),
child: Container(
width: 80,
height: 80,
child: Image.network(
foodList[index]["image"],
fit: BoxFit.cover,
))),
Padding(
padding: EdgeInsets.only(left: 110.0),
child: Text(
foodList[index]["title"],
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 21),
),
),
Padding(
padding: EdgeInsets.only(left: 110.0, top: 50),
child: Text(
"최소주문 ${foodList[index]["price"]}원".toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Colors.grey[500]),
),
),
Padding(
padding: EdgeInsets.only(left: 265.0, top: 20),
child: Text(
"${foodList[index]["thx"]}",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Colors.grey[500]),
),
)
],
)
저는 이렇게 작성했답니다! 위치는 padding 값을 줘서 조정했습니다. 다음으로 저희는 해당 Container를 클릭했을 때 변화를 줘야 하기 때문에 selectIndex라는 int 변수를 하나 지정해주겠습니다. 값은 0으로 해주시면 됩니다.
class _Practice2State extends State<Practice2> {
int selectIndex = 0;
해당 ui는 Widget을 onTap 했을 경우 Container를 둘러싼 border 색상이 변경되고 반갑습니다 라는 텍스트가 정성껏 모시겠습니다 로 변경이 되는 것을 확인하실 수 있습니다. 근데 내가 어떻게 Widget을 tap 했다는 걸 보여줄 수 있을까요? 그때 사용하는 Widget은 여러 가지가 있겠지만 지금은 그중에서 GestureDetector라는 Widget을 사용해보겠습니다. GestureDetector은 onTap이라는 함수를 꼭 가져야 하는데요. 이 함수를 통해 몇 번째 index를 tap 했는지 알려주겠습니다. Stack Widget을 GestureDetector로 감싸주시고요. ontap함수를 불러 selectIndex에 index를 넣어주겠습니다.
GestureDetector(
onTap: (){
setState(() {
selectIndex = index;
print(selectIndex);
});
setState함수는 화면이 변화하는걸 즉시 반영해주는 걸로 알고 계시면 좋을 것 같습니다. 다음 Container를 둘러싼 border에 색상과 애니메이션을 추가하기 위해 기존 Container에 Animated를 붙여주고 아래와 같이 작성해줍니다.
AnimatedContainer(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
margin: EdgeInsets.only(bottom: 10),
duration: Duration(milliseconds: 500),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: selectIndex == index ? Colors.pink[200] : Colors.white,
width: 2,)),
color부분을 보시면 삼항 연산자를 사용했는데요. 풀어서보면 selectIndex가 index가 일치할 경우에만 Colors.pink를 보여주고 일치하지 않을경우 Colors.white를 보여준다는 뜻입니다. ?는 해당 조건에 참, : 해당조건에 거짓 이라고 이해하시면 되겠습니다. 마지막으로 반갑습니다라는 text를 index가 일치할경우 정성껏 모시겠습니다로 변경해보는 작업을 진행해보겠습니다.
Padding(
padding: EdgeInsets.only(left: 265.0, top: 20),
child: selectIndex != index ? Text(
"${foodList[index]["thx"]}",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Colors.grey[500]),
): Text("정성껏\n모시겠습니다.",style: TextStyle(fontWeight: FontWeight.bold),),
)
위와 마찬가지로 삼항연산자를 사용했습니다 selectIndex와 index가 일치하지 않을 경우에 반갑습니다라는 text를 보여주고 일치할 경우 정성껏 모시겠습니다.라는 text가 나오도록 설계를 해봤습니다.
import 'package:flutter/material.dart';
class Practice2 extends StatefulWidget {
const Practice2({Key key}) : super(key: key);
@override
State<Practice2> createState() => _Practice2State();
}
class _Practice2State extends State<Practice2> {
int selectIndex = 0;
List foodList = [
{
"title": "군침이 마카롱",
"price": 3900,
"image":
"https://t1.daumcdn.net/cfile/tistory/99758C355F7F04AA25",
"thx": "반갑습니다."
},
{
"title": "햄깅이 가게",
"price": 1900,
"image":
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRYxaq4udWruQnbE2t4mcoeZTP6h4PYsjMO9g&usqp=CAU",
"thx": "반갑습니다."
},
{
"title": "루시우 가게",
"price": 7900,
"image": "https://t1.daumcdn.net/cfile/tistory/267ACB4E57ADC00536",
"thx": "반갑습니다."
}
];
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(
"가게 이름",
style: TextStyle(color: Colors.black),
),
centerTitle: true,
backgroundColor: Colors.white,
elevation: 3.0,
),
body: Center(
child: Container(
width: 400,
height: 400,
child: ListView.separated(
separatorBuilder: (context, index) => SizedBox(
height: 30,
),
itemCount: foodList.length,
itemBuilder: (BuildContext context, int index) {
return
GestureDetector(
onTap: (){
setState(() {
selectIndex = index;
print(selectIndex);
});
// Navigator.push(context, MaterialPageRoute(builder: (context)=>Pick(index: index,title: foodList[index]["title"],)));
},
child: AnimatedContainer(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
margin: EdgeInsets.only(bottom: 10),
duration: Duration(milliseconds: 500),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: selectIndex == index ? Colors.pink[200] : Colors.white,
width: 2,)),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(60),
child: Container(
width: 80,
height: 80,
child: Image.network(
foodList[index]["image"],
fit: BoxFit.cover,
))),
Padding(
padding: EdgeInsets.only(left: 110.0),
child: Text(
foodList[index]["title"],
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 21),
),
),
Padding(
padding: EdgeInsets.only(left: 110.0, top: 50),
child: Text(
"최소주문 ${foodList[index]["price"]}원".toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Colors.grey[500]),
),
),
Padding(
padding: EdgeInsets.only(left: 265.0, top: 20),
child: selectIndex != index ? Text(
"${foodList[index]["thx"]}",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Colors.grey[500]),
): Text("정성껏\n모시겠습니다.",style: TextStyle(fontWeight: FontWeight.bold),),
)
],
)),
);
}),
),
),
);
}
좀 더 심화학습으로 원하는 가게를 하나 더 만들어서 추가해보는 것도 도움이 될 것 같습니다. 글로 설명을 하려니 빠진 부분과 제가 아직 많이 부족하다는 생각도 느끼네요. 부족한 설명을 들어주셔서 감사합니다. 도움이 되셨다면 하트 한 번씩 눌러주시면 감사하겠습니다.