반응형
사진 등을 격자 형태로 보여주고 싶을 때 보통 GridView 위젯을 사용한다. 이번 포스팅에서는 다음과 같이 카드UI를 그리드뷰를 활용하여 격자모양으로 배치해볼 것이다.
1. GridView로 배치할 item 만들기
<전체 코드>
class _GridItem extends StatelessWidget {
String assetName;
String itemLabel;
SkinType skinType;
final SkinControllor skinController = Get.find();
_GridItem(
{required this.assetName,
required this.itemLabel,
required this.skinType,
super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 150,
height: 150,
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: DEFAULT_PINK,
offset: Offset(0, 0),
blurRadius: 10,
spreadRadius: 1,
)
]),
child: OutlinedButton(
onPressed: () {
skinController.updateSkinType(skinType);
print(skinController.skinType);
},
style: OutlinedButton.styleFrom(
primary: DEFAULT_PINK,
backgroundColor: skinController.skinType == this.skinType
? DEFAULT_PINK
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0), // 둥근 모서리 설정
),
side: BorderSide(
color: DEFAULT_PINK,
width: 3,
strokeAlign: BorderSide.strokeAlignOutside,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image(
image: AssetImage(assetName),
width: 120,
height: 107,
),
Text(
itemLabel,
style: TextStyle(
fontFamily: "BMJUA",
fontSize: 18,
color: Colors.black.withOpacity(0.8),
),
),
],
),
),
);
}
}
다음 코드를 활용해서 GridView에서 활용할 item을 만들 수 있다.
String assetName, itemLabel;
SkinType skinType;
- 위젯에 필요한 데이터를 저장하는 변수들입니다. assetName은 이미지 자산의 경로, itemLabel은 텍스트 라벨, skinType은 피부 타입을 나타냅니다.
final SkinControllor skinController = Get.find();
- 미리 만들어둔 SkinController 인스턴스를 가져옵니다. Get.find()는 GetX 패키지를 사용하여 의존성을 관리합니다.
return Container(
width: 150,
height: 150,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: DEFAULT_PINK,
offset: Offset(0, 0),
blurRadius: 10,
spreadRadius: 1,
)
],
),
// ...
);
- 위젯의 바깥쪽을 감싸는 Container입니다. 여기서 크기, 모양, 그림자 등을 설정합니다.
- width: 150, height: 150: 이 컨테이너의 너비와 높이를 각각 150픽셀로 지정합니다. 이는 위젯이 차지할 공간의 크기를 결정합니다.
- decoration: BoxDecoration(...): 컨테이너의 배경, 테두리, 그림자 등을 설정합니다. BoxDecoration을 사용해 이러한 스타일링 옵션들을 정의합니다.
- boxShadow: [...]: 컨테이너에 그림자 효과를 추가합니다. 이는 위젯이 더 입체적으로 보이게 하는 데 도움이 됩니다.
- BoxShadow(...): 그림자의 세부 사항을 정의합니다.
- color: DEFAULT_PINK: 그림자의 색상을 지정합니다. 이 예에서는 DEFAULT_PINK라는 사용자 정의 상수를 사용하고 있습니다.
- offset: Offset(0, 0): 그림자의 위치를 결정합니다. Offset(0, 0)은 그림자가 컨테이너의 정중앙에 위치하도록 합니다.
- blurRadius: 10: 그림자의 흐림 정도를 결정합니다. 여기서 10은 그림자가 얼마나 멀리 퍼져 나갈지를 나타냅니다.
- spreadRadius: 1: 그림자의 확산 정도를 결정합니다. 1은 그림자가 컨테이너 주변에 약간 확산되도록 합니다.
OutlinedButton(
onPressed: () {
skinController.updateSkinType(skinType);
print(skinController.skinType);
},
style: OutlinedButton.styleFrom(
primary: DEFAULT_PINK,
backgroundColor: skinController.skinType == this.skinType
? DEFAULT_PINK
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0), // 둥근 모서리 설정
),
side: BorderSide(
color: DEFAULT_PINK,
width: 3,
strokeAlign: BorderSide.strokeAlignOutside,
),
),
// ...
)
- OutlinedButton(...): 사용자가 클릭할 수 있는 버튼을 정의합니다. 이 버튼은 onPressed 콜백을 통해 상호작용을 처리합니다.
- style: OutlinedButton.styleFrom(...): 버튼의 스타일을 정의합니다. styleFrom 메서드를 사용하여 여러 스타일링 옵션을 적용합니다.
- primary: DEFAULT_PINK: 버튼의 주요 색상을 지정합니다. 이 경우, 사용자 정의 색상 DEFAULT_PINK가 사용됩니다.
- backgroundColor: ... ? DEFAULT_PINK : Colors.white: 버튼의 배경색을 조건부로 설정합니다. 만약 skinController.skinType이 현재 위젯의 skinType과 같다면 DEFAULT_PINK를 배경색으로 사용하고, 그렇지 않다면 흰색을 사용합니다.
- shape: RoundedRectangleBorder(...): 버튼의 모양을 둥글게 지정합니다. RoundedRectangleBorder를 사용하여 모서리의 반경을 20.0으로 설정합니다.
- side: BorderSide(...): 버튼의 테두리 스타일을 정의합니다. BorderSide를 사용하여 테두리 색상을 DEFAULT_PINK로, 너비를 3픽셀로, 테두리 정렬을 바깥쪽으로 설정합니다.
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image(
image: AssetImage(assetName),
width: 120,
height: 107,
),
Text(
itemLabel,
style: TextStyle(
fontFamily: "BMJUA",
fontSize: 18,
color: Colors.black.withOpacity(0.8),
),
),
],
)
- Column(...): 이미지와 텍스트 라벨을 수직으로 정렬하는 컬럼 위젯입니다.
- mainAxisAlignment: MainAxisAlignment.center: 컬럼의 주 축(main axis)을 중심으로 자식 위젯들을 정렬합니다. 여기서 MainAxisAlignment.center는 자식들이 컬럼의 중앙에 위치하도록 합니다.
- crossAxisAlignment: CrossAxisAlignment.center: 컬럼의 교차 축(cross axis)에 대한 자식 위젯들의 정렬을 지정합니다. CrossAxisAlignment.center는 자식들이 교차 축의 중앙에 위치하도록 합니다.
- children: [...]: Column 위젯 안에 배치될 자식 위젯들의 목록입니다.
- Image(...): 이미지를 표시하는 위젯입니다. AssetImage(assetName)을 사용하여 assetName 변수에 저장된 이미지 자산을 불러옵니다. width와 height 속성을 통해 이미지의 크기를 설정합니다.
- Text(...): 텍스트를 표시하는 위접입니다. itemLabel 변수의 값을 표시합니다.
- style: TextStyle(...): 텍스트의 스타일을 정의합니다. 여기서는 BMJUA라는 사용자 지정 글꼴을 사용하며, 글꼴 크기를 18로 설정하고, 색상을 약간 투명한 검정색으로 지정합니다.
2. 이 아이템들 GridView로 배치하기
GridView.count(
crossAxisCount: 2,
mainAxisSpacing: 22,
crossAxisSpacing: 22,
scrollDirection: Axis.vertical,
children: [
_GridItem(
assetName: 'asset/img/skin_dog1.png',
itemLabel: '머리',
skinType: SkinType.head,
),
_GridItem(
assetName: 'asset/img/skin_dog2.png',
itemLabel: '몸통',
skinType: SkinType.body,
),
_GridItem(
assetName: 'asset/img/skin_dog3.png',
itemLabel: '다리',
skinType: SkinType.legs,
),
_GridItem(
assetName: 'asset/img/skin_dog4.png',
itemLabel: '연접부',
skinType: SkinType.joint,
),
],
)
- crossAxisCount: 2: GridView의 가로축(교차 축)에 표시될 항목의 개수를 설정합니다. 여기서는 한 줄에 두 개의 항목이 표시되도록 설정되어 있습니다.
- mainAxisSpacing: 22: 항목들 사이의 수직 간격(주 축 방향)을 설정합니다. 여기서는 각 항목 사이에 22픽셀의 공간이 있습니다.
- crossAxisSpacing: 22: 항목들 사이의 수평 간격(교차 축 방향)을 설정합니다. 이 값도 22픽셀로 설정되어, 수직 간격과 동일합니다.
- scrollDirection: Axis.vertical: 스크롤 방향을 설정합니다. Axis.vertical은 세로 방향으로 스크롤할 수 있음을 의미합니다. 이는 사용자가 더 많은 항목을 볼 수 있도록 위젯이 세로로 확장될 수 있음을 의미합니다.
- children: [...]: GridView에 배치될 자식 위젯들의 목록입니다. 이 경우, 여러 개의 _GridItem 인스턴스가 배열로 제공됩니다. 각 _GridItem은 특정 피부 타입(SkinType)과 관련된 이미지(assetName)와 라벨(itemLabel)을 포함합니다.
반응형