-
[Fluttet] 플러터 앱 예제 가게 이름 선택하기 예제 (하) (삼항연산자)Flutter 2022. 1. 1. 14:20728x90
안녕하세요! 이전에 했던 예제를 이어서 진행해보겠습니다. 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); });
가게 클릭시 변화하는 INDEX 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),), ) ], )), ); }), ), ), ); }
좀 더 심화학습으로 원하는 가게를 하나 더 만들어서 추가해보는 것도 도움이 될 것 같습니다. 글로 설명을 하려니 빠진 부분과 제가 아직 많이 부족하다는 생각도 느끼네요. 부족한 설명을 들어주셔서 감사합니다. 도움이 되셨다면 하트 한 번씩 눌러주시면 감사하겠습니다.
728x90'Flutter' 카테고리의 다른 글
[Flutter] 배달의 민족 댓글을 코딩으로? (dart class연습) (1) 2022.01.02 [Flutter] 공공데이터포털 api를 이용한 미세먼지 앱 예제 (0) 2022.01.01 [Flutter] 플러터 앱 예제 가게 이름 선택하기 (상) (map 활용하기) (0) 2021.12.30 [Flutter] BottomNavigationBarItem laberText Stryle 적용하기 (2) 2021.12.13 [Flutter] Listview.builder를 사용한 예제만들기 (Listview.builder를 사용해봅시다.) (0) 2021.12.04