본문 바로가기
스파르타/Flutter

[Flutter] 클론코딩(Shazam) 3.첫번째 페이지 - ( week 2 )

by bakcoding_sparta 2023. 4. 18.

현재 페이지 구현은 난이도 순서대로 진행되었다. 마지막 첫 번째 페이지는 비교적 난도가 높은 작업이다.

 

3. 첫번째 페이지

상단부터 작업을 한다.

상단에는 아이콘과 텍스트가 배치되어 있다.

return SafeArea(
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Icon(Icons.settings),
              Text("라이브러리"),
              Icon(null),
            ],
          )
        ],
      ),
    );

아이콘과 텍스트 두 위젯만 넣고 spaceBetween으로 정렬하면 양옆으로 위젯들이 붙게 되는데 이때 Icon(null)을 해주면 텍스트가 중앙에 배치되는 요령이 있다.

 

아이콘을 정렬해 주는데 Padding으로 감싸고 padding: const EdgeInsets.only(top: 8.0)로 여백을 주면 텍스트도 함께 밀려지게 되는데 여기서 주축과 부축에 대해서 인지를 해야 한다. 부축인 crossAxisAlignment가 중앙으로 잡혀있기 때문에 텍스트도 함께 여백이 들어가는데 이를 start로 정렬시켜준다.

              crossAxisAlignment: CrossAxisAlignment.start,

 

그 아래 아이콘의 경우 기본 아이콘이 아닌 이미지이기 때문에 해당 아이콘을 ImageIcon을 사용해서 가져온다.

Row(
              children: [
                ImageIcon(
                  NetworkImage("https://i.ibb.co/hxNbZ8p/shazam.png"),
                  size: 18,
                ),
                SizedBox(width: 12),
                Text(
                  "Shazam",
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.w600,
                  ),
                )
              ],
            ),

 

 

GridView

GridView를 사용해서 리스트를 생성한다. 사용방법은 ListView와 거의 동일하며 속성값으로 crossAxisCount의 값을 필요로 한다. 오버플로우를 방지하기 위해 해당 위젯은 Expanded로 감싼다.

 

SizedBox(height: 16),
            Text(
              "최근 Shazam",
              style: TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.w700,
              ),
            ),
            SizedBox(height: 16),
            Expanded(
              child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                ),
                itemBuilder: (context, index) {
                  return Text("hello");
                },
              ),
            ),

 

안에 들어갈 아이템들은 이미지, 텍스트, 텍스트, 이미지의 형태이다. 

여기서 사용할 데이터는 songs 변수에서 가져다가 쓴다. 

 

Expanded(
              child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  childAspectRatio: 3 / 5,
                ),
                itemCount: songs.length,
                itemBuilder: (context, index) {
                  var song = songs[index];
                  String title = song['title']!;
                  String artist = song['artist']!;
                  String imageUrl = song['imageUrl']!;
                  return Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(
                        Radius.circular(8),
                      ),
                    ),
                    child: Column(
                      children: [
                        Image.network(imageUrl),
                        Text(title),
                        Text(artist),
                        Image.network(
                            "https://i.ibb.co/KG9m5QS/applemusic.png"),
                      ],
                    ),
                  );
                },
              ),
            ),

songs를 순회하면서 song으로 저장하고 안에 있는 데이터인 title, artist, imageUrl을 가지고 아이템을 생성한다.

 

이미지에 테두리 넣는 방법은 ClipRRect를 사용하면 된다.

ClipRRect(
                            borderRadius: BorderRadius.only(
                              topLeft: Radius.circular(8),
                              topRight: Radius.circular(8),
                            ),
                            child: Image.network(
                              imageUrl,
                              fit: BoxFit.cover,
                              height: MediaQuery.of(context).size.width *
                                  0.5 *
                                  5 /
                                  3 *
                                  .55,
                            )),

높이를 일정 비율로 유지되도록 값을 준다. width에 비례하게 값이 변경되도록해서 기기 폭과 상관없이 이미지가 그리드의 높이에 맞춰서 변하게 한다.

 

그리드에 그림자를 준다.

Container(
                    margin: EdgeInsets.all(4),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.all(
                        Radius.circular(8),
                      ),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.grey.withOpacity(0.5),
                          blurRadius: 1,
                          spreadRadius: 1,
                        ),
                      ],
                    ),

BoxShadow를 사용해서 그림자를 줄 수 있다. 이 값은 배열로 받는다.

적용시키면 이상해 보이는 데 BoxDecoration의 색상을 변경해 주면 해결된다.

 

기타 여백과 스타일등을 다듬는 걸로 마무리한다.