ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Fluttet] 플러터 앱 예제 가게 이름 선택하기 예제 (하) (삼항연산자)
    Flutter 2022. 1. 1. 14:20
    728x90

    안녕하세요! 이전에 했던 예제를 이어서 진행해보겠습니다. 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
Designed by Tistory.